摘要:構造函數對于被實例化的,我們稱之為構造函數,及使用關鍵字調用的,對于它們來說,會被改變,指向實例。上栗子全局賦上屬性通過關鍵字創建實例,改變函數內部指向注解通過這個栗子,我們可以看出,通過創建構造函數的實例,使得的指向改變,指向了實例本身。
用栗子說this
function 函數 thisBug年年有,今年特別多
對于JavaScript這么靈活的語言來說,少了this怎么活!
對于沒有實例化的function,我們稱之為函數,即沒有用new關鍵字調用的函數,對它們來說,this一律指代全局。
上栗子
var position = "outer"; function test(){ position = "inner"; } console.log(this.position); // outer test(); console.log(this.position); // inner 原因:內部未用var聲明發生“變量提升”,污染全局變量。構造函數 this
對于被實例化的function,我們稱之為構造函數,及使用new關鍵字調用的function,對于它們來說,this會被改變,指向實例。
上栗子
var name = "person"; // 全局this賦上屬性name function Person(name){ this.name = name; this.say = function () { console.log("My name is "+this.name); } this.show = function () { console.log(this); } } var william = new Person("william"); //通過new關鍵字創建實例,改變函數內部this指向 console.log(this.name); //person william.say(); //My name is william william.show(); //Person {name: "william", say: ... 注解:通過這個栗子,我們可以看出,通過創建構造函數的實例,使得this的指向改變,指向了實例本身。原型對象 this
每一個函數對象在創建的時候,都會自動添加一個prototype屬性,這個prototype其實是一個指針,指向這個函數的原型對象。 你可以通過prototype指針給這個函數對象的原型對象添加屬性,在實例化函數對象后,可以通過this來訪問原型對象上的屬性。
上栗子
function Person(){ console.log(this.name); } Person.prototype.name = "william"; //給原型對象上賦name屬性 var person = new Person(); // 通過this.name訪問原型對象上的屬性,打印 "william"
這還不夠,咱們為函數對象直接添加同名,而不在原型對象上添加
function Person(){ this.name = "Jack"; console.log(this.name); } Person.prototype.name = "william"; var person = new Person(); // 打印 "Jack"
這里有一個值得注意的地方:
Object.create this當你構造函數中存在和原型對象中同名的屬性或方法時,原型對象中的屬性或方法會被隱藏,你只會訪問到構造函數中的屬性或方法`
通過Object.create創建函數對象實例,而不使用new關鍵字,也就是說它不會去調用構造函數
上栗子
function Person(name){ this.name = name; this.showName = function () { console.log(this.name + " in constructor"); } } //在構造函數中的屬性和方法,均同名 Person.prototype.name = "jack"; Person.prototype.showName = function () { console.log(this.name + " in prototype"); }; //在原型對象中的屬性和方法,均同名 var william = new Person("william"); var jack = Object.create(Person.prototype); william.showName(); // william in constructor jack.showName(); // jack in prototype 注解: - 使用new關鍵字創造的實例調用了構造函數的屬性和方法 - 使用Object.create創造的實例調用了原型對象的屬性和方法原型鏈 this
原型鏈用于實現繼承,當沒有找到需要屬性或方法時,會順著原型鏈向上繼續尋找。
上栗子
function Father(){ this.name = "father"; } //可以看做"父類" Father.prototype.showName = function () { console.log(this.name); }; function Son(){ this.name = "son"; } //可以看做"子類" Son.prototype = new Father(); //這步是關鍵! var mike = new Son(); mike.showName(); // son 注解: - 首先要強調的是JavaScript中沒有"父類","子類","繼承"這樣的東西,我們只是通過原型鏈來實現這樣的設計模式。 - 通過這一步 Son.prototype = new Father(); 我們將"子類"的prototype指針指向了"父類"函數對象設計模式:繼承
為什么這樣就能實現繼承呢? 首先要想明白為什么實例能訪問構造函數的原型對象 在JavaScript中,有一個內部的屬性,在火狐,谷歌瀏覽器中,將這個內部屬性暴露了出來,就是它 __proto__
上栗子(瀏覽器中)
mike.__proto__ // Father {name: "father", showName: function} Son.prototype //Father {name: "father", showName: function} mike.__proto__ === Son.prototype // true 通過這個內部屬性,我們可以訪問到實例的構造函數的原型對象
再來一枚(瀏覽器中)
mike.__proto__.__proto__ //Father {showName: function} Father.prototype //Father {showName: function} mike.__proto__.__proto__ === Father.prototype // true 我們現在通過__proto__訪問到了"父類"的原型對象! 繼承得以實現!
補充一句:
我們可以訪問到Son的name屬性的值,卻訪問不到Father的name屬性的值,是因為 - mike是Son的實例(實例能做什么...?) - Father中的name沒有對外開放,可以看做是私有屬性總結
主要探討了
- function作為函數、構造函數、原型對象時,this的指代情況
- 擴展了另一種實例化方式Object.create
- 細說了原型鏈原理和實現,模擬了繼承的設計模式
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91494.html
摘要:在腳本中,默認指向一個空對象,并不是指向,也不是指向。舉個栗子,在函數執行后,覆蓋原先的值我們在外部定義了一個名為的全局變量,它會被默認添加到全局的屬性上。總結在不同的執行環境中的默認指代通過省略聲明變量導致變量提升現象的發生及預防 侃侃JavaScript中的this this為何如此多變? this總是跟它的執行上下文有關,而在JavaScript總會有開辟新的執行上...
摘要:閉包執行上下文決定了變量作用域而閉包,它其實是一種決策,是一種模式,讓我們可以靈活的改變變量作用域。所以,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋梁。只要咱們弄明白閉包,其中的自然跑不掉。 閉包 this 執行上下文決定了變量作用域 而閉包,它其實是一種決策,是一種模式,讓我們可以靈活的改變變量作用域。 按慣例,上栗子 var global = glo...
摘要:為了實現這個正義偷笑又合理的訴求,你得先學會今天要介紹的設計模式,因為你們公司的這個流程可能就是用今天這個模式設計的。狀態模式對開閉原則的支持并不太好,新增狀態時,不僅得增加狀態類,還得修改原來已經有的狀態,讓之前的狀態切換到新增的狀態。一、定義你是否經常請(偷)假(懶)?是不是對公司萬惡的請假申請流程深惡痛絕。有沒有想過偷偷改造這個萬惡的系統,從 申請->項目經理審批->部門審批->老板審...
摘要:寫在前面在一款應用的整個生命周期,我們都會談及該應用的數據安全問題。用戶的合法性與數據的可見性是數據安全中非常重要的一部分。 寫在前面 在一款應用的整個生命周期,我們都會談及該應用的數據安全問題。用戶的合法性與數據的可見性是數據安全中非常重要的一部分。但是,一方面,不同的應用對于數據的合法性和可見性要求的維度與粒度都有所區別;另一方面,以當前微服務、多服務的架構方式,如何共享Sessi...
摘要:而在中是迭代器生成器,被創造性的拿來做異步流程控制了。當執行的時候,并不執行函數體,而是返回一個迭代器。行代碼再看看文章開頭的行代碼首先生成一個迭代器,然后執行一遍,得到的是一個對象,里面再執行。 廣告招人:阿里巴巴招前端,在這里你可以享受大公司的福利和技術體系,也有小團隊的挑戰和成長空間。聯系: qingguang.meiqg at alibaba-inc.com 首先請原諒我的標題...
閱讀 3768·2021-08-30 09:47
閱讀 3690·2019-08-30 15:56
閱讀 677·2019-08-30 14:18
閱讀 698·2019-08-29 16:17
閱讀 2065·2019-08-29 11:07
閱讀 642·2019-08-26 13:53
閱讀 3443·2019-08-26 10:26
閱讀 2491·2019-08-23 18:30