js
let fn1 = function() {
alert(1)
},
fn2 = function() {
alert(2)
}
fn1.call(fn2) //1
fn1.call.call(fn2) //2
1.首先来看fn1.call(fn2)
call的方法是Function这个大类上的原型方法,目的是将前面方法的this指向括号里的对象的this指向。
执行fn1.call(fn2)的时候,会将fn1的函数里面的this指向fn2,并执行fn1,但是fn1方法里面并没有使用this,所以依旧执行fn1,输出1
2.接着来看fn1.call.call(fn2)
先简单看成(fn1.call).call(fn2),fn1.call这里的call里面的this就指向fn1,所以将fn1.call变成一个待执行的call函数,并且该函数会使用了里面的this,而第二个call又将this指向了fn2,所以调用fn1就执行了fn2。
function Foo() {
getName = function() {
console.log(1)
}
return this
}
Foo.getName = function() {
console.log(2)
}
Foo.prototype.getName = function() {
console.log(3)
}
var getName = function() {
console.log(4)
}
function getName() {
console.log(5)
}
Foo.getName() //2
getName() //4
Foo().getName() //1
getName() //1
new Foo.getName () //2
new Foo().getName () //3
new new Foo.getName () //报错
Foo.getName()
执行Foo.getName()就是执行Foo这个对象(Foo这个类可以看做一个对象,万物皆对象),找到function() { console.log(2)},所以输出2。
getName()
这里考的知识点是变量与函数重名的清空。
正常来说,定义变量时杜绝与函数重名的。如果发生这种清空,当变量没有赋予初始值,只是简单声明变量,那么函数的优先级会更高。而如果变量被赋予初始值,那么变量的优先级就会更高。
Foo().getName()
首先执行Foo这个函数,执行该函数就会让getName重新赋值。返回this其实就是window,然后执行this.getName(),打印出1
getName()
直接执行该函数,该函数已经被Foo()执行的时候更改,所以打印也是1
**new Foo.getName () **
**new Foo().getName () **
**new new Foo.getName () **
这几个涉及的知识点主要是运算符优先级。
new Foo.getName ():new Foo无参数,所以首先会执行Foo.getName,然后再依次执行。
new Foo().getName ():new Foo()带了参数,就会优先执行new Foo(),返回一个this,this就是一个新对象,它本身没有getName这个函数,所以会执行创建他这个对象的类的原型对象上的方法。
*new new Foo.getName () *:首先执行new Foo.getName (),没有返回值,默认返回undefined,然后再new,报错。