從零開始學 Web 之 JS 高階(三)apply與call,bind,閉包和沙箱
一、apply 和 call 方法
apply 和 call 都可以改變呼叫其的函式或方法中的 this 指向。
不同的是傳入引數時,apply 有兩個引數,第二個引數是陣列;call 從第二個引數開始是呼叫其的函式的所有引數。
使用方法:
1、apply的使用語法:
函式名.apply(物件,[引數1, 引數2,... ]);
方法名.apply(物件,[引數1, 引數2,... ]);
2、call的使用語法:
函式名.call(物件,引數1, 引數2,... );
方法名.call(物件,引數1, 引數2,... );
1、函式呼叫apply和call
function f1(x, y) { console.log(x+y +this); // 這裡面的this是window return x+y; } var r1 = f1.apply(null, [10,20]); // 列印30 window,傳入的是null,所以this指向還是window console.log(r1); // 30 var r2 = f1.call(null, 10,20);// 列印30 window console.log(r2); // 30
//函式改變 this 的指向
var obj = {};
var r1 = f1.apply(obj, [10,20]); // 列印30 window,傳入的是Obj,所以this指向是Obj
console.log(r1); // 30
var r2 = f1.call(obj, 10,20);// 列印30 Obj
console.log(r2); // 30
2、方法呼叫apply和call
// 方法改變 this 的指向 function Person(age) { this.age = age; } Person.prototype.eat = function () { console.log(this.age); // this 指向例項物件 }; function Student(age) { this.age = age; } var per = new Person(18); var stu = new Student(20); per.eat.apply(stu); // 列印 20 per.eat.call(stu); // 列印 20
由於 eat 方法已經指向了 Student 了,所以列印 20,而不是 18.
問題:我們知道函式也是物件,函式可以呼叫 apply 和 call 方法,但是這兩個方法並不在這個函式這個物件的例項函式中,那麼在哪裡呢?
解答:所有的函式都是 Function 的例項物件,而 apply 和 call 就在 Function 建構函式的原型物件中。
二、bind方法
bind 是複製的意思,也可以改變呼叫其的函式或方法的 this 指向,引數可以在複製的時候傳進去,也可以在複製之後呼叫的時候傳進去。
使用語法:
1、函式名.bind(物件, 引數1, 引數2, ...); // 返回值是複製的這個函式
2、方法名.bind(物件, 引數1, 引數2, ...); // 返回值是複製的這個方法
1、函式呼叫 bind
function f1(x, y) {
console.log(x + y + this);
}
// 1.引數在複製的時候傳入
var ff = f1.bind(null,10,20); // 這只是複製的一份函式,不是呼叫,返回值才是
ff();
// 2.引數在呼叫的時候傳入
var ff = f1.bind(null); // 這只是複製的一份函式,不是呼叫,返回值才是
ff(10,20);
2、方法呼叫 bind
function Person(age) {
this.age = age;
}
Person.prototype.eat = function () {
console.log(this.age); // this 指向例項物件
};
function Student(age) {
this.age = age;
}
var per = new Person(18);
var stu = new Student(20);
var ff = per.eat.bind(stu);
ff(); // 20
bind和call,apply的區別:[update:2018.07.26]
bind繫結this的指向之後,不會立即呼叫當前函式,而是將函式返回。
而call,apply繫結this指向後會立即呼叫。
如果我們在不知道什麼時候會呼叫函式的時候,需要改變this的指向,那麼只能使用bind。
比如:在定時器中,我們想改變this的指向,但是又不能立即執行,需要等待2秒,這個時候只能使用bind來繫結this。
setInterval(function(){
// ...
}.bind(this), 2000);
三、閉包
1、閉包的概念
有一個函式 A 中有一個函式或者物件 B,那麼函式或者物件 B 可以訪問函式 A 中的資料,那麼函式 A 的作用域就形成了閉包。
2、閉包的模式
函式模式的閉包:函式中包含函式。
物件模式的閉包:函式中包含物件。
3、閉包的作用
快取資料,延長作用域鏈。
4、閉包的優缺點
也是快取的資料,導致在閉包的範圍內一直起作用。
5、閉包的應用
快取資料,函式中的資料,外面可以使用。
如果想要快取資料,就把這個資料放在外層的函式和裡層的函式之間。這樣不停的呼叫裡層函式,相當於外層函式裡的資料沒有得到及時釋放,就相當於快取了資料。
// 函式閉包
function A() {
var num = 10;
return function () {
return num++;
}
}
var func = A();
console.log(func());
console.log(func());
console.log(func());
// 物件閉包
function A() {
var num = 10;
return {
age: num++
};
}
var func = A();
console.log(func.age);
四、沙箱
沙箱:一小塊的真實環境,裡面發生的事情不會影響到外面。相同的操作,相同的資料都不會和外面發生衝突。
作用:避免命名衝突。
比如:自呼叫函式裡面就相當於一個沙箱環境。
(function (){
}());
五、區分偽陣列和真陣列
// 真陣列
var arr = [10,20,30];
// 偽陣列
var obj = {
0:10,
1:20,
2:30,
length: 3
};
// 真陣列的訪問
for(var i=0; i<arr.length; i++) {
console.log("真陣列的訪問:"+arr[i]);
}
// 偽陣列的訪問
for(var j=0; j<obj.length; j++) { // 錯誤:物件中沒有length方法
console.log("偽陣列的訪問:"+obj[j]);
}
方法一、使用 length 來區分
這樣看起來,真陣列和偽陣列就沒法區別了。
但是真陣列的長度 length 可以改變,偽陣列不可以,貌似可以區分了。
但是,你還記得有個 arguement 這個偽陣列(物件)的 length 是可以改變的,方法一區分失敗。
方法二、使用陣列的方法 forEach 來鑑別
因為每個陣列都是 Array 的例項物件,而 forEach 在 Array 的原型物件中,所以其他的偽陣列是不能使用的。方法二成功。
相關推薦
從零開始學 Web 之 JS 高階(三)apply與call,bind,閉包和沙箱
一、apply 和 call 方法 apply 和 call 都可以改變呼叫其的函式或方法中的 this 指向。 不同的是傳入引數時,apply 有兩個引數,第二個引數是陣列;call 從第二個引數開始是呼叫其的函式的所有引數。 使用方法: 1、apply的使用語法: 函式名.apply(物件,[引數1
從零開始學 Web 之 JS 高階(二)原型鏈,原型的繼承
一、原型鏈 原型連結串列示的是例項物件與原型物件之間的一種關係,這種關係是通過__proto__原型來聯絡的。 1、原型的指向改變 例項物件的原型 __proto__ 指向的是該物件的建構函式中的原型物件 prototype,如果該物件的建構函式的 prototype 指向改變了,那麼例項物件中的原型 _
從零開始學 Web 之 JavaScript 高階(一)原型,貪吃蛇案例
一、複習 例項物件和建構函式之間的關係: 1、例項物件是通過建構函式來建立的,建立的過程叫例項化。 2、如何判斷一個物件是不是某種資料型別? 通過構造器的方法。例項物件.constructor === 建構函式名字 (推薦使用)例項物件 instanceof 建構函式名字 二、原型 1、原型的引入 由
從零開始學 Web 之 JS 高級(二)原型鏈,原型的繼承
console 多少 程序 cat hub inf 當前 構造函數 調用 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔 博客園:
從零開始學 Web 之 JS 高級(三)apply與call,bind,閉包和沙箱
master 操作 console 概念 釋放 分享圖片 成功 num 命名沖突 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔
【高德地圖API】從零開始學高德JS API(七)——定位方式大揭祕
摘要:關於定位,分為GPS定位和網路定位2種。GPS定位,精度較高,可達到10米,但室內不可用,且超級費電。網路定位,分為wifi定位和基站定位,都是通過獲取wifi或者基站資訊,然後查詢對應的wifi或者基站位置資料庫,得到的定位地點。定位資料庫可以不斷完善不斷補充,所以,
轉載:高德地圖API學習 從零開始學高德JS API(一)地圖展現
摘要:關於地圖的顯示,我想大家最關心的就是麻點圖,自定義底圖的解決方案了吧。在過去,marker大於500之後,瀏覽器開始逐漸卡死,大家都開始尋找解決方案,比如聚合marker啊,比如麻點圖啊。聚合marker裡面還有一些複雜的演算法,而麻點圖,最讓大家頭疼的,就是如何生成麻點圖,如何切圖,如何把圖片貼到地圖
webpack從零開始構建專案之rem問題(三)
使用webpack解決px轉rem的自適應問題 現在的專案配置已經可以正常執行 接下來我們要考慮下一個問題,由於VUE主要適用於移動端,所以我們需要一個自適應方案 由於這是一個大眾需求的剛需方案,所以我們大可不必自己手動去寫JS程式碼,重複造輪子 那麼我
從零開始學 Web 之 Vue.js(三)Vue實例的生命周期
報錯 web 前端 cnblogs 前端 eth code vue 公眾 des 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔
從零開始學 Web 之 Vue.js(四)Vue的Ajax請求和跨域
在線安裝 配置 name php文件 splay .json alert 參考 1.0 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端
從零開始學 Web 之 Vue.js(五)Vue的動畫
一、Vue的動畫 為什麼要有動畫:動畫能夠提高使用者的體驗,幫助使用者更好的理解頁面中的功能; Vue 中也有動畫,不過遠沒有 css3 中的那麼炫酷。只能有一些簡單的變換,但是卻可以配合第三方css動畫庫完成炫酷的變換。 1、過渡的類名 在進入/離開的過渡
從零開始學 Web 之 Vue.js(六)Vue的元件
大家好,這裡是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 部落格園:http://www.cnblogs.com/lvonve/ CSDN:https://blog.csdn.net/lvonve/
從零開始學 Web 之 Vue.js(二)過濾器,按鍵修飾符,自定義指令
大家好,這裡是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 部落格園:http://www.cnblogs.com/lvonve/ CSDN:https://blog.csdn.net/lvonve/
從零開始學 Web 之 Vue.js(一)Vue.js概述,基本結構,指令,事件修飾符,樣式
大家好,這裡是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 部落格園:http://www.cnblogs.com/lvonve/ CSDN:https://blog.csdn.net/lvonve/
從零開始學 Web 之 DOM(一)DOM的概念,對標簽操作
關註 1.5 pan 什麽 tin p標簽 nod text == 大家好,這裏是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關註。在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,
從零開始學 Web 之 DOM(四)節點
def clas scrip while p標簽 設置 ner 操作 text 大家好,這裏是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關註。在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相
從零開始學 Web 之 BOM(三)offset,scroll,變速動畫函數
樣式 清理 java mar dde sof mov har width 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔 博客園:
從零開始學 Web 之 jQuery(二)獲取和操作元素的屬性
eight images idt 隱藏 lis 屬性 ner master lin 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔
從零開始學 Web 之 jQuery(六)為元素綁定多個相同事件,解綁事件
png 好用 添加 方式 執行 存在 區別 也會 地址 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔 博客園:http://ww
從零開始學 Web 之 jQuery(七)事件冒泡,事件參數對象,鏈式編程原理
eval uri turn 定位 return 也會 否則 ont sele 大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公眾號:Web前端之巔 博客