读书笔记:JS设计模式与开发实践
1 this
JS的this着是指向一个对象,而具体指向哪个对象是运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。
1-A this指向
- 作为对象的方法调用
- 作为普通函数调用
- 构造器调用
- Function.prototype.call 或 Function.prototype.call调用
1-A-a 作为对象的方法调用时,this指向该对象
var obj = {
a: 1,
getA : function(){
console.log(this === obj);
console.log(this.a);
}
}
obj.getA()
1-A-b 作为普通函数(不作为对象的属性)被调用时,this指向全局对象。在浏览器里即window,在node里即global
window.name = 'globalName';
var getName = function(){
return this.name;
}
console.log(getName());
有时我们会遇到一些困扰,比如div节点是事件函数,callback内部的this指向了window,但我们想让它指向该div节点
可在外部保存_this指向,es6解决方式为箭头函数
1-A-c 构造器调用时,this指向new的对象
var MyClass = function(){
this.name = 'sven'
}
var obj = new MyClass()
console.log(obj.name); //sven
1-A-d Function.prototype.call 或 Function.prototype.call可动态改变传入函数this
var obj1 = {
name: 'sven',
getName: function(){
return this.name;
}
}
var obj2 = {
name: 'anne'
}
console.log(obj1.getName()); // sven
console.log(obj1.getName.call(obj2)); // anne
1-B 丢失的this
var obj = {
myName: 'sven',
getName: function(){
return this.myName;
}
}
console.log(obj.getName()); // sven
var getName2 = obj.getName; // undefined
console.log(getName2());
调用getName2 返回undefined是因为:当用变量getName2来引用obj.getName,并且调用时。此时是普通函数调用方式,this指向全局。
2 call 和 apply
能熟练运用这两个方法,是JS程序员进阶重要一步。
2-A call和 apply的区别
apply接受两个参数,第一个参数指定了函数体内this对象的指向,第二个参数为一个带下杆的集合,可是数组或类数组。
var func = function(a, b, c){
console.log([a,b,c]);
}
func.apply(null, [1,2,3])
call 传入的参数数量不固定,第一个参数为this指向,第二个开始,每个参数都被依次传入函数
var func = function (a, b, c) {
console.log([a, b, c]);
}
func.call(null, 1, 2, 3)
当使用call或apply时,如第一个参传入null,函数体内的this会指向默认的宿主对象,浏览器中就是window。但在严格模式下,函数体内的this还是为null
有时我们使用call或apply的目的不在于指定this指向,而是另有用途,如借用其他对象的方法。那么我们可传入null来代替某个具体的对象
Math.max.apply(null, [1,2,5,3,4])
2-B call和apply用途
- 改变this指向
- Function.prototype.bind
- 借用其他对象的方法