js中關于call原始碼的決議
- call、apply、bind
- call
call、apply、bind
三個方法都是改變函式中的 this 指向,只有是Function的實體才可以使用這三個方法,
首先函式中的this 不能放在等號的左邊,不能直接被修改;否則會拋出例外,
這時就需要call、apply、bind這三個方法來改變this的指向,
function fn(){
this=100; //Uncaught SyntaxError: Invalid left-hand side in assignment
console.log(this);
}
fn()
call
單call的情況下:
- 讓fn的屬性名是call的屬性值執行,但是fn沒有call屬性,所以需要通過**proto向原型查找,找到了Function原型中的call**,并且讓call函式執行了,
- 當call執行時,改變了fn中的this,讓這個this指向call方法第一個實參,(如果不傳參或者傳入null \ undefined,非嚴格模式下fn的this指向window)
- call中傳入的第二個引數及之后的引數,都傳給fn這個函式,
function fn(a,b,){
console.log(this);// [100,200]
console.log(a);// 10
console.log(b);// 11
}
fn.call([100,200],10,11)
一個引數多次呼叫call方法(二次及以上):
function fn1() {
console.log(1)
console.log(this)
}
function fn2() {
console.log(2)
console.log(this)
}
fn1.call(fn2) // 1 ? fn2(){}
fn1.call.call(fn2) // 2 window
我們封裝一下call基本的原始碼:
- 單call
function fn1(a, b) {
console.log(this) // obj
console.log(a) // 11
console.log(b) // 12
}
let obj = { name: "newThis" }
Function.prototype.Mycall = function (obj, ...ary) {
obj = obj || window // 如果不傳引數 就讓其指向window
obj.$fn = this; // this就是fn1函式
var result = obj.$fn(...ary);
delete obj.$fn // 自己添加的屬性,最后要清掉,避免影響使用
return result // 把函式的回傳值return出去
}
fn1.Mycall(obj, 11, 12)
- 多call
function fn1() {
console.log(this)
}
function fn2() {
console.log(this)
}
Function.prototype.Mycall = function (arg) {
arg = arg || window // 如果不傳引數 就讓其指向window
arg.$fn = this; // this是fn1.Mycall ; fn1.Mycall就是在fn1中查找屬性名為Mycall的屬性值 就是Mycall這個方法本身
var result = obj.$fn(); //相當于fn2.Mycall() 在這把上文單call在走一邊,因為沒有傳參所以fn2中的this指向window
delete arg.$fn // 自己添加的屬性,最后要清掉,避免影響使用
return result // 把函式的回傳值return出去
}
fn1.Mycall.Mycall(fn2) //暫不考慮傳多個引數的情況
如有不對,歡迎指出問題所在,定當認真修改,
鏈接: 博客主頁.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/236092.html
標籤:其他
上一篇:如何更快的學習JQuery基礎
下一篇:物件及原型
