物件,原型,上下文環境,作用域,閉包等問題深入理解

2021-08-31 09:45:14 字數 3723 閱讀 7847

物件

物件是屬性的集合,重點:是乙個集合,意思是有乙個個屬性整合在了一起,組成了乙個集合,這個集合叫做物件,另外,這個屬性是以鍵值對的形式存在的,鍵是乙個字串,比如a,比如name等,值可以是任意型別,比如陣列,function,字串,數字

prototype(原型)

每乙個函式建立的時候,系統會自動給這個函式附加乙個叫prototype的屬性,這個prototype,我們稱作為原型,而這個叫做prototype,也就是原型的屬性本身是乙個物件,它的本身只有乙個屬性就是constructor,意思是將這個原型指向這個函式,從而不會弄錯父級.

雖然這個prototype只有乙個自帶的屬性,但是我們可以給它擴充套件,例如:

function aa(){}

aa.prototype=

另外,這邊還有乙個__proto__,其指向的是該原型物件的prototype,這個屬性是乙個私有屬性,是各個大瀏覽器廠商新增的乙個屬性,但是因為其廣泛的使用,被大家所流傳,其作用和prototype一樣,也是乙個原型,如果硬要說區別,大概就是顯性原型(prototype)和隱性原型(__proto__)把,看個例子

function aa(){}

aa.prototype.__proto__ === object.prototype //true

或function aa(){}

let a=new aa(){}

a.__proto__ === aa.prototype //true

解釋:

a是aa的例項物件,因此,它的__proto__指向的是其原型物件的prototype,也就是aa.prototype

aa.prototype不僅是a的原型物件,同時自己也是乙個例項物件,所以它的__proto__是obejct.prototype

注意1:頂級的obejct.prototype,它的__proto__是null,因為它已經是頂級了,沒有原型物件

原型鏈

原型鏈,原型鏈,說白了就是一條鏈,也就是一層一層的繼承下來的一條鏈式,例如:

function foo(){}

foo.prototype={}

let foo=new foo();

這裡的foo,是繼承的foo上的屬性方法,而foo除了自身prototype上的方法屬性,還有從object上繼承來的方法和屬性,從foo->foo->object,這就是一條原型鏈,foo不僅從foo處繼承到了屬性方法,還從object處繼承到了屬性和方法

注意1:如何判斷是否是自己自由的屬性或方法,而不是從原型鏈上繼承到的,這裡有乙個方法可以判斷,hasownproperty(),如下例

function aa(params) {}

let a=new aa();

a.name=1;

aa.prototype.name=1;

aa.prototype.age=2;

console.log(aa.prototype); //

console.log(a); //

for (item in a)

上下文環境

1.var,let,const

宣告乙個變數通常有三種方法,var以及在es6中引入的let,const

var:是一種全域性宣告,即使宣告在呼叫之後,也只會是顯示undefined,而不會報錯

console.log(a) //undefined

var a=10;

let和const:呼叫必須在宣告之後,如果在之前,就會報錯

console.log(a,b) //丟擲異常錯誤

let a=10;

const b=10;

2.this

this,這個值在任何地方都有值,而且情況很複雜

第一種情況,當做建構函式中被呼叫了

function foo()

let a=new foo();

sonsole.log(a.name,a,age) //aa,bb

如果函式被當做建構函式使用,那麼這時的this代表的是new出來的物件

但是

如果函式是被直接呼叫了,而不是當做建構函式使用,沒有例項化,如下

function foo()

foo()

那麼,此時的的this指向的是window

第二種情況,函式作為物件的乙個屬性

如果函式作為物件的乙個屬性,並且被作為屬性呼叫時,那麼此時的this指向的是當前的這個obj

let a=

console.log(this.x) //1

a.y();

如果函式作為乙個物件的屬性,但是不是作為乙個屬性被呼叫的,那麼此時的this指向的是window

let a=

console.log(this.x) //undefined

let ax=a.y;

ax();

此時的this指向的是當前傳入的這個物件

let obj=

let a=function()

console.log(this.x) //10

a.call(obj)

第四中情況

全域性和呼叫普通函式

全域性情況下的this === window,永遠等於

被當做普通函式呼叫時,this也永遠指向window,例如

let a=

console.log(this.x); //undefined

ax();

3.函式,函式宣告

函式也是乙個全域性屬性即使呼叫在宣告之後,依舊可以被使用

aa() //10

function aa())(fn)

這邊,max的取值為10,而不是15,原因是上面提到的乙個函式的作用域取值要去建立的那個作用域取值,而不是呼叫的那個作用域。

正常情況下,當乙個函式呼叫結束以後,這個函式的上下文環境會被銷毀,包括其中的變數,但是,閉包的核心就是不希望這個函式被銷毀

未完待續..

原型 執行上下文 作用域 閉包 記憶體溢位 洩漏

函式高階 原型與原型鏈 給原型物件新增屬性 一般是方法 顯式原型與隱式原型 原型鏈 object的原型物件是原型鏈盡頭 屬性問題 探索instanceof function是通過new自己產生的例項 執行上下文與執行上下文棧 函式宣告提公升 執行上下文 全域性執行上下文 開始執行全域性 函式執行上下...

JS作用域 執行上下文 遞迴與閉包

目錄 作用域全域性作用域 函式作用域 執行上下文 函式執行上下文 執行上下文棧 作用域與執行上下文的區別 遞迴閉包 產生閉包的條件 閉包的作用 使用注意 記憶體洩漏 記憶體溢位 一種程式執行出現的錯誤 作用域指乙個變數的作用範圍。它是靜態的 相對於上下文物件 在編寫 時就確定了。作用 隔離變數,不同...

作用域和上下文

作用域分為全域性作用域和區域性作用域。區域性作用域中可訪問全域性變數,但是全域性作用域中無法訪問某一區域性作用域中的區域性變數。上下文常常代表this變數的值及其指向,它決定乙個函式怎麼被呼叫,但乙個函式被作為物件的乙個方法被呼叫的時候,this總是指向呼叫這個方法的物件。this往往指向當前函式的...