數組追加數組
//用apply拼接 var arr1=[12,'name:foo',2048]; var arr2=['Joe','Hello']; Array.prototype.push.apply(arr1,arr2); console.log(arr1);//(5) [12, "name:foo", 2048, "Joe", "Hello"] //用call拼接 var arr1=[12,'name:foo',2048]; var arr2=['Joe','Hello']; Array.prototype.push.call(arr1,arr2); console.log(arr1);//(4) [12, "name:foo", 2048, Array(2)] Array(2) ["Joe", "Hello"]是arr2只佔一位,而後在第三位下面又分2位
獲取數組中的最大值和最小值app
//對比call和apply (參數明確時用call) var numbers=[25,456,86,-45]; var maxNum=Math.max.apply(Math,numbers)//傳入的是一個數組 console.log(maxNum);//456 var numbers=[25,456,86,-45]; var maxNum=Math.max.call(Math,25,456,86,-45)//傳入的一個個參數 console.log(maxNum);//456
驗證是不是數組(前提是toString()方法沒有被重寫過)函數
var arr=[1,2,3,4,5]; function isArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]' ; } isArray(arr); console.log(isArray(arr))//true
apply的用法this
function log(msg) // 常規寫法 { console.log(msg); } log(1);//1 log(1,2);//1 1
用apply的方法spa
function log() { console.log.apply(console,arguments); } log(1);//1 log(1,2);//1 2
bind的用法prototype
//常規寫法
var foo = { bar : 1, eventBind: function(){ console.log(this) var _this = this; $('.someClass').on('click',function(event) { // Act on the event console.log(_this.bar); //1 }); } } foo.eventBind();
//bind的寫法
var foo = { bar : 1, eventBind: function(){ $('.someClass').on('click',function(event) { // Act on the event console.log(this.bar); //1 }.bind(this)); } } foo.eventBind();
bind() 建立了一個函數,當這個click事件綁定在被調用的時候,它的 this 關鍵詞會被設置成被傳入的值(這裏指調用bind()時傳入的參數)。所以,這裏咱們傳入想要的上下文 this(其實就是 foo ),到 bind() 函數中。
而後,當回調函數被執行的時候, this 便指向 foo 對象。code
案例對象
var bar = function(){ console.log(this.x); } var foo = { x:3 } var sed = { x:4 } var func = bar.bind(foo).bind(sed); func(); //3 此時輸出的爲3 var fiv = { x:5 } var func = bar.bind(foo).bind(sed).bind(fiv); func(); //3 //此時輸出的爲3
在Javascript中,屢次 bind() 是無效的。更深層次的緣由,bind() 的實現,至關於使用函數在內部包了一個 call / apply,第二次 bind() 至關於再包住第一次 bind() ,故第二次之後的 bind 是沒法生效的。
bind()返回的內容blog
var obj = { x: 81, }; var foo = { getX: function() { return this.x; } } var a = foo.getX.bind(obj); //81 console.log(a()); //81 // console.log(foo.getX.bind(obj)()); //81 call和apply是當即執行,而bind返回的是函數
call 方法事件
//使用call方法調用匿名函數 var peoples=[ {name:'Jane',age:16}, {name:'Maria',age:15} ] for(var i=0;i<peoples.length;i++){ (function(i){ this.print=function(){ console.log(i+"----" +this.name+"---"+this.age); } this.print(); }).call(peoples[i],i) }
//使用call方法調用父構造函數 function Product(name,price){ this.name=name; this.price=price if(price < 0){ throw RangeError('Connot create product'+this.name+'with a negative price'); } } function Food(name,price){ Product.call(this,name,price); this.category='food'; } var cheese = new Food('feta', 5); console.log(cheese);//Food {name: "feta", price: 5, category: "food"}
簡單用法
function cat(){ } cat.prototype={ food:"fish", say:function(){ alert("I love "+this.food); } } var blackCat = new cat; blackCat.say(); var whiteDog = {food:"bone"}; console.log(whiteDog); blackCat.say.apply(whiteDog);
總結:
apply 、 call 、bind 三者都是用來改變函數的this對象的指向的;
apply 、 call 、bind 三者第一個參數都是this要指向的對象,也就是想指定的上下文;
apply 、 call 、bind 三者均可以利用後續參數傳參;
apply 、 call 會馬上執行,而bind的回調函數
apply傳入的是數組apply(this,[argu1,argu2,argu3,argu4]),call是call(this,argu1,argu2,argu3,argu4),若是傳入的參數個數是已知的,能夠用call方法。若是個數未知,用apply方法。
-------------------------------------------------------------------------------------------------2018-06-04-----------------------------------------------------------------------------------------------------------------------
var obj={ name:"Jack", getName:function(age,gender){ console.log(this.name) console.log(age) console.log(gender) } } obj.getName(12,'男')//obj本身調用 var People={ name:"Jane" } obj.getName.call(People,15,'男') //call obj.getName.apply(People,[15,'男']) //apply var a = obj.getName.bind(People,15,'男') // bind返回的是一個回調函數 a()
當bind和call複用的時候
function fn(name){ this.name=name console.log(this.name) } var a = fn.bind.call(fn,{},'Jack'); //第一個參數是bind要調用的函數,第二個參數是call函數執行函數執行時的上下文,依次是傳入函數的參數 a() //等同於 var orgBindFun = Function.prototype.bind; var b = orgBindFun.call(fn,null,'Jack') b()