this的应用
this的应用
函数执行 看方法前面是否有“点” 没有“点” this是window【严格模式下是undefined】 有“点” “点”前面是谁this就是谁
const fn = function(){console.log(this)
}
let obj = {name:'gh',fn:fn
}fn()
obj.fn()
给当前元素的某个事件行为绑定方法 当事件行为触发 方法中的this是当前元素本身【排除attachEvent】
document.body.addEventListener("click", function () {console.log(this);
});
构造函数体中的this是当前类的实例
function Factory() {this.name = "gh";this.age = 24;console.log(this);
}
let f = new Factory();
箭头函数中没有执行主体 所用到的this都是其所处上下文中的this
let demo = {name: "DEMO",fn() {console.log(this);setTimeout(function () {console.log(this);}, 1000);setTimeout(() => {console.log(this);}, 1000);},
};
demo.fn();
可以基于Function.prototype上的call/apply/bind去改变this指向
func函数基于__proto__找到Function.prototype.call 把call方法执行
在call方法内部 【call执行的时候】call(context->obj,…params->10,20)
- 把func中的this 改为obj
- 并且把params接收的值当作实参传递给func函数
- 并且让func函数立即执行
func函数基于__proto__找到Function.prototype.bind 把bind方法执行
在bind方法内部
- 和call/apply的区别:并没有把func立即执行
- 把传递进来的boj/10/20等信息存储起来【闭包】
- 执行bind返回一个新的函数 例如称作:proxy 把proxy绑定给元素的事件 当事件触发执行的是返回的proxy 在proxy内部 在去把func执行 把this和值都改变为之前存储的哪些内容
function func(x, y) {console.log(this, x, y);
}let obj = {name: "OBJ",
};func.call(obj, 10, 20);
func.apply(obj, [10, 20]);document.body.addEventListener("click", func.bind(obj, 10, 20));
点击后
实现call
//原理:利用“点”定this机制 context.xxx = self "obj.xxx = func" => obj.xxx()
Function.prototype.call = function call(context, ...params) {// this/self->func context->obj params->[10,20]let self = this,key = Symbol("KEY"),result;context == null ? (context = window) : null;/^(object|function)$/i.test(typeof context) ? (context = Object(context)) : null;context[key] = self;result = context[key](...params);delete context[key];return result;
};
实现bind
Function.prototype.bind = function bind(context, ...params) {//this/self -> func context -> obj params -> [10,20]let self = this;return function proxy(...args) {//把func执行并且改变this args->是执行proxy的时候可能传的值self.apply(context, params.concat(args));};
};
鸭子类型
克隆arr返回一个新数组 可以使用arr.slice()前拷贝
实现一个slice
Array.prototype.slice = function () {result = [];for (let i = 0; i < this.length; i++) {result.push(this[i]);}return result;
};
将arguments变成数组
Array.from(arguments)、[…arguments]、Array.prototype.slice.call(arguments)…
function func() {[].forEach.call(arguments, (item) => {console.log(item);});
}func(1, 2, 3);