call
一句話介紹call:
- call()方法在使用一個(gè)指定的this值和若干指定的參數(shù)值的前提下調(diào)用某個(gè)函數(shù)或方法茵烈。
舉個(gè)例子:
var obj = {
value: 1
};
function parson() {
console.log(this.value);
}
bar.bind(foo); //1
- call改變了this指向,指向了parson
- parson函數(shù)執(zhí)行了计寇。
模擬步驟
- 講函數(shù)設(shè)置為對(duì)象的屬性
2.執(zhí)行該函數(shù)
3.刪除該函數(shù)
// 第一步
obj.fn = parson
//第二步
obj.fn();
// 第三步
detele obj.fn;
第一次嘗試
Function.prototype.call2 = function (context) {
// 首先獲取調(diào)用call的函數(shù)扩淀,用this可以獲取;
context.fn = this;
// 傳入?yún)?shù)確定怎么辦吠撮?我們可以從arguments對(duì)象中取值伊滋,去除第二個(gè)到最后一個(gè)參數(shù)
let args = [];
for (var i = 1; i < arguments.length; i+) {
args.push('arguments[' + i + ']');
}
// 不定參的問(wèn)題解決了,我們要吧這個(gè)參數(shù)放在要執(zhí)行的函數(shù)的參數(shù)中去;
// 可以使用eval方法拼成一個(gè)函數(shù)
eval('context.fn(' + args + ')');
// context.fn(); // 執(zhí)行函數(shù)
detele context.fn;
}
// 測(cè)試一下
var obj = {
value: 1
}
function parson() {
console.log(name);
console.log(age);
console.log(this.value);
}
parson.call2(obj, 'name', 15);
// name
// 15
// 1
ok 這樣基本就實(shí)現(xiàn)了call的基本功能郁轻,不過(guò)還有兩小點(diǎn)要注意一下翅娶。
1. this可以傳參null,當(dāng)為null的時(shí)候好唯,指向window;
舉個(gè)例子:
var value = 1;
function parson() {
console.log(this.value);
}
parson.call(null) // 1
2.函數(shù)是可以有返回值的
舉個(gè)例子:
var obj = {
value: 1
}
function parson(name, age) {
return {
value: this.value,
name: name,
age: age
}
}
console.log(parson.call(obj, 'name', 15))
// Object {
// value: 1,
// name: 'name',
// age: 15
//}
好的竭沫,我們下改進(jìn)后的代碼
Function.prototype.call2 = function (context) {
context.fn = context || window; // 設(shè)置一個(gè)默認(rèn)值
let args = [];
for (var i = 1; i < arguments.length; i+) {
args.push('arguments[' + i + ']');
}
var result = eval('context.fn(' + args + ')');
detele context.fn;
return result;
}
// 測(cè)試一下
var obj = {
value: 1
}
function parson() {
console.log(name);
console.log(age);
console.log(this.value);
}
parson.call2(obj, 'name', 15);
// name
// 15
// 1
到此,我們就完成了call的實(shí)現(xiàn)骑篙!
apply的模擬試下
apply的實(shí)現(xiàn)跟call類(lèi)似,在這里直接給代碼蜕提。
Function.prototype.apply2 = function (context, arr) {
context = context || window;
context.fn = this;
var result;
if (arr) {
var args = [];
for (var i = 1; i < arguments.length; i++) {
args.push('argsuments[' + i + ']');
}
result = eval('context.fn(' + args + ')');
} else {
result = context.fn()
}
detele = context.fn;
renturn result;
}