Front-end-learning-to-organize-notes
Front-end-learning-to-organize-notes copied to clipboard
this的原理,call,apply,bind的区别
都是改变this的指向,区别主要在于方法的实现形式和参数传递上的不同。call和apply方法都是在调用之后立即执行的。而bind调用之后是返回原函数,需要再调用一次才行 2、①:函数.call(对象,arg1,arg2....) ②:函数.apply(对象,[arg1,arg2,...]) ③:var ss=函数.bind(对象,arg1,arg2,....) 3、总结一下call,apply,bind方法: a:第一个参数都是指定函数内部中this的指向(函数执行时所在的作用域),然后根据指定的作用域,调用该函数。 b:都可以在函数调用时传递参数。call,bind方法需要直接传入,而apply方法需要以数组的形式传入。 c:call,apply方法是在调用之后立即执行函数,而bind返回函数,需要将函数再执行一遍。有点闭包的味道。
JavaScript深入之call的模拟实现
Function.prototype.myCall = function (context = window) {
// console.log(context); // foo
context.fn = this;
// console.log(this); // bar:function
var arr = [...arguments];
arr.shift();
let result = context.fn(...arr);
delete context.fn;
return result;
}
// 测试一下
var foo = {
value: 1
};
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value);
}
bar.myCall(foo, 'kevin', 18);
// kevin
// 18
// 1
JavaScript深入之apply的模拟实现
Function.prototype.myApply = function (context = window, arr) {
context.fn = this;
var result = context.fn(...arr);
delete context.fn
return result;
}
// 测试一下
var foo = {
value: 1
};
function bar(name, age) {
console.log(name)
console.log(age)
console.log(this.value);
}
bar.myApply(foo, ['kevin', 18]);
// kevin
// 18
// 1
JavaScript深入之bind的模拟实现
Function.prototype.myBind = function (context = window) {
//判断调用者是否为函数
if (typeof this !== 'function') {
return new TypeError('Error');
}
//保存this调用方法的本身
const that = this;
//获取参数
const args = Array.from(arguments).slice(1);
//一个空函数,用来维护原型
var tmp = function () { }
let fn = function () {
//由于返回一个函数,因此对于new fn();
//不能改变this指向
if (this instanceof fn) {
return new that(...args, ...arguments);
} else {
return that.apply(context, args.concat(...arguments));
}
}
//维护原型
tmp.prototype = that.prototype;
fn.prototype = new tmp();
//返回函数
return fn;
}
var foo = {
value: 1,
};
function bar(name, age) {
this.name = name;
this.age = age;
console.log(name);
console.log(age);
console.log(this.value);
}
let fn = bar.myBind(foo, 'Chocolate', 18);
fn();
console.log(foo);
// Chocolate
// 18
// 1
// { value: 1, name: 'Chocolate', age: 18 }