摘要:構(gòu)造函數(shù)創(chuàng)建一個對象上邊這個例子,我們通過構(gòu)造函數(shù)創(chuàng)建了一個實例,從這個實例到他的原型到最后得,他們之間得關(guān)系,就形成了一個原型鏈和首先上邊這個例子里邊,我們聲明了一個構(gòu)造函數(shù),在后再這個構(gòu)造函數(shù)里邊有一個的屬性。
構(gòu)造函數(shù)創(chuàng)建一個對象
function Person() { } var person = new Person(); person.name = "zhangsan"; console.log(person.name) // zhangsan
上邊這個例子,我們通過構(gòu)造函數(shù)創(chuàng)建了一個實例,從這個實例到他的原型到最后得object,他們之間得關(guān)系,就形成了一個原型鏈
prototype __proto__ 和 constructor首先上邊這個例子里邊,我們聲明了一個構(gòu)造函數(shù),在后再這個構(gòu)造函數(shù)里邊有一個prototype的屬性。
注意這個prototype屬性,是只有函數(shù)才會有屬性
Person.prototype.name = "zhangsan"; var person1 = new Person(); var person2 = new Person(); console.log(person1.name) // zhangsan console.log(person2.name) // zhangsan
首先我們看到再函數(shù)的prototype屬性上邊我們定義了一個name屬性,然后通過new創(chuàng)建了兩個實例,
然后通過調(diào)用實例的name屬性,也可以拿到構(gòu)造函數(shù)prototype屬性上邊的name屬性,
那么這個prototype到底是有什么用處呢,
prototype
這個只有函數(shù)才會有的屬性,他其實指向了一個對象,而這個對象就是調(diào)用了構(gòu)造函數(shù)創(chuàng)建實例的原型
,可以理解成是person1,person2在創(chuàng)建的時候從他們的原型把原型的屬性委托給了person1和person2
這里為什么不叫他繼承,因為繼承的定義是賦值一個一模一樣的實例出來,但是js里邊并不會復(fù)制
proto
這個__proto__屬性是每個對象實例都會有的一個屬性,這個屬性也會指向該對象的原型
function Person() {} var person1 = new Person(); console.log(person1.__proto__ === Person.prototype); // true
可以粘貼一下代碼到瀏覽器打印一下person1 可以看到__proto__這個屬性
constructor
constructor這個屬性之前我也叫他構(gòu)造函數(shù),叫習(xí)慣了,因為每個原型上邊都會有一個constructor這個屬性,指向其相關(guān)的構(gòu)造函數(shù)
function Person() {} console.log(Person === Person.prototype.constructor); // true原型鏈的查找機制
首先在你創(chuàng)建一個實例的時候,你去讀取實例上邊的屬性,他會首先再實例上邊去查找,如果找不到,那么就去這個實例的原型上邊去找,如果還是找不到,就會去原型的原型上邊去找,直到最后找到Object對象,當(dāng)然object對象也是有原型的 就是null
記得之前的時候,遇到過這么一個問題就是typeof null的 時候為什么是個object,記得當(dāng)時得到的答案是說null是一個對象的空指針,從現(xiàn)在來看null打印object是有原因的
那么還是查找不到的話會怎么樣的,不要慌(.?ー?), 他會返給你一個undefined(.?ー?)
最后拉一張圖
圖中藍色的這個鏈狀的結(jié)構(gòu)的線就是原型鏈
js的作用域首先什么叫做作用域
作用域是指程序源代碼中定義變量的區(qū)域。作用域規(guī)定了如何查找變量,也就是確定當(dāng)前執(zhí)行代碼對變量的訪問權(quán)限。
JavaScript 采用詞法作用域(lexical scoping),也就是靜態(tài)作用域。
var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); } bar();
網(wǎng)上拿來的例子,直接說過程
在執(zhí)行階段執(zhí)行foo的時候,直接在foo尋找value ,因為js是靜態(tài)作用域,所以在foo里邊沒有找到的時候,直接去上一層找,最后結(jié)果是1
var value = 1; function bar() { var value = 2; console.log(value); } bar();
同理這段代碼bar里邊有value 直接打印2
那么再看一個例子
var scope = "global scope"; function checkscope(){ var scope = "local scope"; function f(){ return scope; } return f(); } checkscope();
這個例子會打印出什么,大家可以猜一猜
結(jié)果就是local scope
那么為什么上邊的第一段代碼里邊同樣是在函數(shù)里邊執(zhí)行另一個函數(shù),但是他不會用第一個函數(shù)里邊的變量呢,
原因就是js是靜態(tài)作用域,js執(zhí)行一個函數(shù)的時候分為兩個階段,首先會解析一變,這個時候確定了詞法作用域和this指向,屬性聲明等,然后才是函數(shù)執(zhí)行階段
函數(shù)的作用域是基于函數(shù)創(chuàng)建的位置的,所以第一段代碼和下邊這段代碼的函數(shù)作用域是不想同的
說到這里的時候,我在上文中提到了執(zhí)行上下文和函數(shù)執(zhí)行的過程,之前在我得另一篇博客里邊寫道過,有興趣的可以去看下 js的堆棧隊列
以上是我對js原型鏈和作用域的一些認識,有不足的希望指正,之前在博客園寫的。搬過來的
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/105461.html
摘要:我們用一張圖表示構(gòu)造函數(shù)和實例原型之間的關(guān)系好了構(gòu)造函數(shù)和實例原型之間的關(guān)系我們已經(jīng)梳理清楚了,那我們怎么表示實例與實例原型,也就是或者和之間的關(guān)系呢。 開篇: 在Brendan Eich大神為JavaScript設(shè)計面向?qū)ο笙到y(tǒng)的時候,借鑒了Self 和Smalltalk這兩門基于原型的語言,之所以選擇基于原型的面向?qū)ο笙到y(tǒng),并不是因為時間匆忙,它設(shè)計起來相對簡單,而是因為從一開始B...
摘要:我們用一張圖表示構(gòu)造函數(shù)和實例原型之間的關(guān)系好了構(gòu)造函數(shù)和實例原型之間的關(guān)系我們已經(jīng)梳理清楚了,那我們怎么表示實例與實例原型,也就是或者和之間的關(guān)系呢。 開篇: 在Brendan Eich大神為JavaScript設(shè)計面向?qū)ο笙到y(tǒng)的時候,借鑒了Self 和Smalltalk這兩門基于原型的語言,之所以選擇基于原型的面向?qū)ο笙到y(tǒng),并不是因為時間匆忙,它設(shè)計起來相對簡單,而是因為從一開始B...
摘要:原型鏈與繼承當(dāng)談到繼承時,只有一種結(jié)構(gòu)對象。如果對該圖不怎么理解,不要著急,繼續(xù)往下看基于原型鏈的繼承對象是動態(tài)的屬性包指其自己的屬性。當(dāng)使用操作符來作用這個函數(shù)時,它就可以被稱為構(gòu)造方法構(gòu)造函數(shù)。 原型鏈與繼承 當(dāng)談到繼承時,JavaScript 只有一種結(jié)構(gòu):對象。每個實例對象(object )都有一個私有屬性(稱之為proto)指向它的原型對象(prototype)。該原型對象也...
摘要:原文發(fā)自我的博客易企秀招聘啦首先我們先來回顧以下中出現(xiàn)的原型繼承原型繼承自如果我們要在上查詢一個定義在的屬性會先在上查找如果沒有查到那么會順著原型鏈去查找所以以下判別式均為如果我們做如下操作原型鏈并沒有被訪問一個新的會被加入到的屬性中去新的 原文發(fā)自我的博客 xiaoyu2er.github.io 易企秀招聘啦! JavaScript Prototypal Inheritance 首先...
摘要:深入之繼承的多種方式和優(yōu)缺點深入系列第十五篇,講解各種繼承方式和優(yōu)缺點。對于解釋型語言例如來說,通過詞法分析語法分析語法樹,就可以開始解釋執(zhí)行了。 JavaScript深入之繼承的多種方式和優(yōu)缺點 JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點。 寫在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點。 但是注意: 這篇文章更像是筆記,哎,再讓我...
閱讀 2744·2021-11-19 09:40
閱讀 5294·2021-09-27 14:10
閱讀 2099·2021-09-04 16:45
閱讀 1462·2021-07-25 21:37
閱讀 2995·2019-08-30 10:57
閱讀 2981·2019-08-28 17:59
閱讀 1055·2019-08-26 13:46
閱讀 1408·2019-08-26 13:27