原型規(guī)則
所有的引用類型(數(shù)組,函數(shù),對象),都有一個(gè)proto屬性,屬性值是一個(gè)對象
_proto叫隱式原型
var a = {} // 是var a = new Object()的語法糖
function fn(){}
a.name = 'qq'
console.log(a._proto_)
console.log(a.prototype)// 函數(shù)的顯示原型屬性
console.log(a._proto_ === Object.prototype)
//所有的引用類型(數(shù)組,對象,函數(shù)),它的_proto_都指向其構(gòu)造函數(shù)的prototype
//什么叫指向:就是===
[Running] node "C:\Users\ADMINI~1\AppData\Local\Temp\tempCodeRunnerFile.javascript"
undefined
所有的
函數(shù),都有一個(gè)proto屬性,屬性值是一個(gè)對象prototype叫顯式原型
當(dāng)試圖得到某個(gè)對象的摸個(gè)屬性的時(shí)候,如果這個(gè)對象本身沒有這個(gè)屬性,那么它會(huì)去這個(gè)對象的
_proto_中尋找,也就是這個(gè)對象對應(yīng)的構(gòu)造函數(shù)的prototype中尋找
當(dāng)試圖得到某個(gè)對象的摸個(gè)屬性的時(shí)候,如果這個(gè)對象本身沒有這個(gè)屬性,那么它會(huì)去這個(gè)對象的`_proto_`中尋找,也就是這個(gè)對象對應(yīng)的構(gòu)造函數(shù)的prototype中尋找 function Foo(name, age){ this.name = name; this.age = age; } // 通過函數(shù)的prototype設(shè)置引用類型的屬性 Foo.prototype.alertName = function(){ console.log(this.name,this.age) } var foo = new Foo('lisi',20) // 直接設(shè)置引用類型的屬性 foo.printName = function(){ console.log(this.name,this.age) // 通過對象的屬性來調(diào)用函數(shù)的時(shí)候,無論函數(shù)是自己的屬性還是構(gòu)造函數(shù)的屬性,它的this永遠(yuǎn)指向?qū)ο蟊旧?} foo.printName() foo.alertName() foo.toString() //這個(gè)要去foo._proto_._proto_中找,找不到就不找了 for(var item in foo){ if(foo.hasOwnProperty){ console.log(item) } /* [Running] node "C:\Users\ADMINI~1\AppData\Local\Temp\tempCodeRunnerFile.javascript" lisi 20 lisi 20 name age printName 結(jié)果中沒有構(gòu)造函數(shù)prototype中的屬性,都是直接是foo對象的屬性 */ console.log(item) //結(jié)果中多出了alertName(這是構(gòu)造函數(shù)prototype中的屬性) } [Running] node "C:\Users\ADMINI~1\AppData\Local\Temp\tempCodeRunnerFile.javascript" lisi 20 lisi 20
instanceOf
用來判斷引用類型(對象,數(shù)組等等)屬于哪個(gè)構(gòu)造函數(shù)
原理:如上面的例子,判斷foo是否屬于Foo的邏輯原理就是
判斷foo的proto,一級一級往上,看是否可以對應(yīng)到Foo.prototype
注意
引用類型是
擴(kuò)展:
引用類型和數(shù)據(jù)類型的區(qū)別是
當(dāng)數(shù)據(jù)類型的變量賦值給另一個(gè)變量的時(shí)候,修改其中一個(gè)變量的值,不會(huì)影響另外一個(gè)變量// 基本數(shù)據(jù)類型 var a=10; var b=a; //b=10 a=20; console.log(b); //b還是10當(dāng)把引用類型的變量賦值給另外一個(gè)引用類型變量時(shí),修改其中一個(gè)變量的值,另外一個(gè)變量的值會(huì)隨之改變,看下面的例子:
// 引用類型 var arr1=[1,2,3,4,5]; var arr2=arr1; //arr2=[1,2,3,4,5] arr2[1]=23; console.log(arr1); //arr1=[1,1,3,4,5] var obj1={name:"tom"}; var obj2=obj1; //boj1={name:'tom'} obj2.name="jack"; console.log(obj1.name) //boj1={name:'jack'}
- 基本數(shù)據(jù)類型有這五種:Undefined、Null、String、Number、Boolean。
- 引用類型有這幾種:object、Array、RegExp、Date、Function、特殊的基本包裝類型(String、Number、Boolean)以及單體內(nèi)置對象(Global、Math)。
如何判斷一個(gè)變量是不是數(shù)組類型
用instanceof而不是typeof
var arr = []; arr instanceof Array // true typeof arr // Object,注意,typeOf是無法判斷是否是數(shù)組的
class相關(guān)問題(class與函數(shù)的關(guān)系?class的靜態(tài)方法跟普通方法的對比?)自己提出兩個(gè)有關(guān)的問題并解決
es6中class與函數(shù)的關(guān)系
- es5 中的function 可以用call apply bind 的方式 來改變他的執(zhí)行上下文
但是class 卻不可以 class 雖然本質(zhì)上也是一個(gè)函數(shù) 但是 其內(nèi)(babel)部做了一層代理 來禁止了這種行為
https://blog.csdn.net/qq_37653449/article/details/83306769
es5中函數(shù)定義類
// es5中函數(shù)定義類 function Foo(x,y){ this.x = x; this.y = y; } Foo.prototype.toString = function(){ console.log('(' + this.x + ', ' + this.y + ')') // +用來連接字符串 } var f = new Foo(1,2) f.toString() [Running] node "C:\Users\ADMINI~1\AppData\Local\Temp\tempCodeRunnerFile.javascript" (1, 2)
es6中類的使用方法
// es6中類的使用方法(注意要安裝babel依賴,不然es6用不了) class Foo(x,y) { /* 上一行可以換成Foo.prototype(x,y),因?yàn)镻oint === Point.prototype.constructor //true */ constructor(){ this.x = x; this.y = y; } toString(){ console.log('(' + this.x + ',' + this.y + ')') } } var foo = new Foo(1,2) [Running] node "C:\Users\ADMINI~1\AppData\Local\Temp\tempCodeRunnerFile.javascript" (1, 2)
調(diào)用類的方法也就是調(diào)用原型(prototype)上的方法
class B {} let b = new B(); b.constructor === B.prototype.constructor // true