York's Blog

函数

函数的5种声明

所有的函数都有name属性

  1. function x(输入1,输入2){ return undefined }
    function是关键字,和var差不多都是声明的意思 var 变量可以是七种 ,function x只能是函数 console.log(字符串) ,如果接受的不是字符串,会自动调用x.toString,console.log()永远return undefined,打印什么和返回什么一点关系都没有 x.name=’x’
  2. var x=function (输入1,输入2){ return undefined } 匿名函数 x.name=’x’
  3. var x=function y(输入1,输入2){ return undefined } console.log(y)会报错,不一致,JS垃圾 x.name=’y’
  4. window.Function函数对象

    1
    2
    3
    4
    var fn = new Function('x','y','return x+y') ==> 
    var n=1
    new Function('x','y','return x'+n+'+y')
    fn.name='anonymous' //anonymous翻译为匿名
  5. var f =(x,y)=>{return x+y} 箭头函数一定是匿名函数 ;

    1
    2
    只有一句话,return和{}可以一起去除 sum=(x,y)=>x+y ; 
    只有一个参数,()可以去除 var n2 = n=>n*n

如何调用函数

可以执行代码的对象就叫函数
f.call(asThis,input,input2)
call翻译为调用 f指的是这个对象,asThis会被当做this,[input,input2]会被当做arguments,f.call()执行f这个函数体
call
Function.prototype

eval()给个字符串,当代码执行 eval(“1+1”)==>2

f(1,2) === f.call(undefinef,1,2);f(1,2) 糖sweet的函数调用, f.call(undefinef,1,2)真正的调用,硬核hardcore

this 和 arguments

f.call(undefinef,1,2) undefined=>this , [1,2]=>arguments

  1. call的第一个参数可以用this得到。
    JavaScript为了长得像Java 1.new 2.this
    如果在普通模式下,如果this是undefined,浏览器会自动把this变成window;
    如果在严格模式下,如果this是undefined,this就是undefined
  2. call的后面的参数可以用arguments(伪数组)得到,arguments(伪数组)内存像数组,但是原型链中没有Array.prototype

什么是call stack

call stack(调用堆栈)先入后出
call stack
递归
stack overflow call.stack长度固定的是9641
每次进一个函数就要压一次stack

作用域

  • 只要 有个函数就有个作用域 就近原则
  • 我们只能确定变量是哪个变量,但是不能确定变量的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var a = 1
function f1(){
alert(a) // a是undefined
var a = 2
}
f1.call()
-----------------------------------------
var a = 1
function f1(){
var a = 2
f2.call()
}

function f2(){
console.log(a) // 是1
}
f1.call()
----------------------------------------------------
var liTags = document.querySelectorAll('li')
for(var i = 0; i<\liTags.length; i++){
liTags[i].onclick = function(){
console.log(i) // 点击第3个 li 时,打印 6
}
}
拿到代码直接做——必然会错。请先提升声明

什么是闭包,闭包的用途是什么?

  1. 什么是闭包
    闭包就是函数内部访问函数作用域外的变量,这个变量和这个函数之间的这个环境就叫闭包

    1
    2
    3
    4
    var a = 1
    function fn(){
    console.log(a)
    }

    这个就叫闭包,其实我们天天都在用

  2. 闭包的用途
    闭包可以暂存数据,已经给变量开辟私密空间,避免外部污染 在一个函数作用域中声明一个变量,子函数(访问器)可以操作这个变量,通过return 这个子函数(访问器),
    外面可以访问这一个变量,来达到此目的,外面变量通过得到return的函数,这样外面访问这个函数,这个函数访问父级函数的变量,这样变量就一直存在这个依赖关系无法销毁
    闭包
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function s(){
    var i = 0;
    return function(){
    return ++i;
    }
    }
    var a = s()
    console.log(a())
    console.log(a())
    console.log(a())
    console.log(a())

call、apply、bind 的用法分别是什么?

apply,call和bind都是来改变this的指向的,
第一个参数都是相同的this指向的那个对象
但是apply接受的第二个参数一定是数组
call和bind接受的参数是连续的参数

apply与call立即执行
bind只是先改变this的指向
下面代码代码对上面的详细说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var s = {
a:1,
b:2,
add(name) {
console.log(this.a + this.b)
console.log(name)
}
}

var a = {
a:2,
b:2,
}
var b = {
a:4,
b:2,
}
var c = {
a:5,
b:6,
}
s.add.call(a,"我叫call")
s.add.apply(b,["我叫apply"])
//s.add.bind(c,"我叫bind")此时bind只是改变了this如果要执行需要加上()
s.add.bind(c,"我叫bind")()
//等价于s.add.bind(c)("我叫bind")`

Proudly published with Hexo