关于《你不知道的JavaScript》-隐式丢失
作者Kyle Simpson因为研究js,冷落了妻子儿女。最近在通过这本书来学习JavaScript,今天来为大家介绍其中一小部分内容,其中遇到一些不解和疑惑,希望大佬为我解答。通过这本书我确确实实感受到js的神奇和魅力。
关于this的绑定规则
此书花费两章节全面解析this,其中绑定规则有四种:默认绑定、隐式绑定、显示绑定、new绑定。下面为大家简单介绍:
默认绑定:
function foo() {
console.log( this.a );
}
var a = 2;
foo(); //2
此处函数没有指向this是什么,所以采用了this的默认绑定,从而this指向全局对象。
隐式绑定
function foo() {
console.log( this.a)
}
var obj = {
a : 2,
foo : foo
}
obj.foo(); //2
调用位置会使用obj上下文来引用函数。
隐式丢失
function foo() {
console.log(this.a)
}
var obj = {
a : 2,
foo : foo
}
var dofoo = obj.foo;
var a = "oops";
dofoo();
我的疑惑:为什么WS输出会出现错误?
从图下可以看出,博主使用WebStorm编译此代码输出为“undefined”。但是,正确输出应为“oops”。
错误:
正确:
可见,this.a并没有等于obj.a。虽然dofoo是obj.foo的一个引用,但是实际上,它引用的是foo函数本身,因此此时的dofoo其实就是foo函数本身,因此使用默认绑定,输出则是全局变量的a值“oops”。
显示绑定
function foo() {
console.log( this.a )
}
var obj = {
a : 2
}
foo.call(obj); //2
通过foo.call(…),我们可以在调用foo时强制把它的this绑定到obj上。
但是,显示绑定无法解决丢失绑定的问题,因此书上提出两种解决方法。
1.硬绑定
使用内置方法bind进行绑定。
function foo (sth) {
console.log( this.a, sth);
return this.a + sth;
}
var obj = {
a : 2,
}
var bar = foo.bind(obj);
bar(3); //2 3
2.创建可重复使用的辅助函数。
此处我们创建的bind函数手动将foo函数与对象obj进行绑定并通过返回值获得
function foo (sth) {
console.log( this.a, sth);
return this.a + sth;
}
var obj = {
a : 2,
}
var bind = function (fn, obj) {
return function () {
return fn.apply(obj, arguments)
}
}
var b = bind(foo,obj);
var result = b(3);//2 3
console.log(result);//5
new绑定
function foo(a) {
this.a = a
}
var bar = new foo(2);
console.log(bar.a); //2
至此,简略的介绍了JavaScript的绑定规则。
最后,好好学习,天天向上。