是三種改變函式內部this指向(即函式執行時所在作用域)的方法。
//模擬原始碼/**
* 1. 讓函式立即執行
* 2. 改變函式內部的this指向
*/function.prototype.call = function
call(context)
context = context ?object(context) : window;
context.fn = this; //
改變函式內部的this指向
const args =;
for(let i=1; i)
//立即執行;利用了陣列的tostring()屬性
const r = eval('context.fn('+ args + ')');
delete
context.fn;
return
r;
}
1)第乙個引數
第乙個引數必須是物件,
var n = 123;var obj =
function
a()
//this === window
a.call(); //
window
a.call(null); //
window
a.call(undefine); //
window
a.call(window); //
window
//this === obj
a.call(obj); //
obj//
this === 包裝物件
a.call(5); //
number(5)
2) 其餘的引數
其餘的引數作為函式呼叫時傳入的引數
functionadd(a,b)
//this表示固定當前this的指向; this === window
add.call(this, 1, 2); //
3
3)應用
//呼叫物件的原生方法
var obj =console.log(obj.hasownproperty('tostring')); //
fasle
obj.hasownproperty = function()
console.log(obj.hasownproperty('tostring')); //
true
//obj可以使用原型鏈上的方法,表示在obj的作用域使用hasownproperty的方法
console.log(object.prototype.hasownproperty.call(obj)); //
false
//模擬原始碼/**
* 3. 引數以陣列形式傳遞 */
//throw
new typeerror('the first param should be a function');
} context = context ?object(context) : window;
context.fn = this;
if(!args)
const r = eval('context.fn('+ args +')');
delete
context.fn;
return
r;}
1)第乙個引數和call方法規則相同
2)第二個引數
functionadd(a,b)
null, [1, 2, 3, 4, 5]);
第二個引數還可以是類陣列,如arguments
functionadd(a,b)
function
newadd()
var result = newadd(3,4,5,5);
console.log(result);
//7
3)應用
//1) 查詢陣列的最大值
const arr = [1,3,5];
null, arr); //5//
還可以math.max(...arr); //5//
2) 將陣列的空項轉為undefined;undefine可以被遍歷,空會被遍歷函式忽略
const arr = [1,,4];
null, arr); //
[1,undefined,4] array是陣列的建構函式
//模擬原始碼/**
* 1. bind可以繫結this的指向;bind還可以繫結引數;
* 最後的引數=bind時傳入的引數+新函式的引數
* 2. bind繫結後返回乙個新的函式
* 3. 如果返回的函式被使用了new命令,this指向例項物件
* 4. new命令生成的例項可以找到原有類的原型物件 */
function.prototype.bind = function
bind(context)
return
};//
新生成的函式繼承bind之前的原型物件
function
fn() {}
fn.prototype = this
.prototype;
boundfn.prototype = new
fn();
//返回新函式
return
boundfn;
}
1)第乙個引數
2)剩餘的引數
當bind(thisvalue, ...)後面引數的個數小於原函式的個數時,繫結部分引數;
//繫結部分引數;相當於引數復用,只需要處理剩餘的引數
function
fn(a,b)
var newfn = fn.bind(null, 5)
/*newfn = function(b)
*/console.log(newfn(6)); //
11
3)應用
document.addeventlistener('click', obj.fn.bind(this))//
下面取消繫結無效;因為是不同的函式
document.removeeventlistener('click',obj.fn.bind(this))
正確的寫法寫法應該是
var listener = obj.fn.bind(this);document.addeventlistener('click', listener);
document.removeeventlistener('click', listener);
obj.print = function() .bind(
this
));};
obj.print()
//張三
//張三
//張三
[1, 2, 3].slice(0, 1) //[1]//
等同於array.prototype.slice.call([1, 2, 3], 0, 1) //
[1]//
上面**的意思是在array.prototype.slice物件上呼叫call方法//即
var myslice =function.prototype.call.bind(array.prototype.slice);
console.log(myslice([1,2,3], 0, 1)) // 能呼叫slice的物件是第乙個引數
//同理
var mypush =function.prototype.call.bind(array.prototype.push);
//bind方法傳參也可以被改變
function
f()
var obj =
var mybind =function.prototype.call.bind(function.prototype.bind); // 能呼叫bind方法只能是function
mybind(f, obj)();
//1
2)bind方法是返回乙個新的函式,並不立即執行
應用:1)將類陣列轉為陣列
//1)將類陣列轉為陣列
//bind方法生成乙個新的函式,需要手動執行,後面加()
array.prototype.slice.bind()();
2)給**函式繫結物件
//2)繫結**函式的物件;//
未進行繫結前,**函式中的this一般都是windowvar name = 'hello world';
var obj =)
}}obj.print();
//
使用bind方法繫結**函式中的thisvar name = 'hello world';
var obj =.bind(this))) //}}
obj.print();
//var name = 'hello world';
var obj =).call(that); //
})) }
}obj.print();
apply,bind,call應用小總結
一 最大最小 為什麼 二 將偽陣列轉化為陣列 var arraylike 必須以數字為屬性,必須有length屬性,length多了,就會多加undefined,length少了主動刪減多餘的 var arr array.prototype.slice.call arraylike arr為 1 2...
方法的呼叫 this方法 構造方法
1 呼叫者和被呼叫者方法位於同一類中,呼叫形式如下 this 方法名 在大多數情況下,關鍵字this可以忽略 呼叫者位於被呼叫方法所在類的外部 物件名.方法名或者類名.方法名 抽象類只能作為父類,不能例項化。只能被繼承 抽象方法是一種只有方法宣告而沒有方法體定義的特殊方法,最後有乙個分號 而沒有方法...
例項方法 靜態方法 類方法
首先新建乙個日期date類,屬性為年,月,日,tomorrow 是例項方法,這個最常見,比較簡單,例項方法的第乙個引數是例項物件self 當我們傳入的年月日是2018 6 4這樣的形式,我們就需要先進行字串處理,在這裡使用了元組的拆包 這是最基本的方式,但是這樣寫會有乙個問題,每次傳參都需要進行字串...