摘要:碰過的一個有趣的問題實現(xiàn)一個構(gòu)造函數(shù),有一個屬性,每次調(diào)用該值加。共有方法看下面的代碼可以發(fā)現(xiàn),被重復創(chuàng)建了如果不想方法或者屬性在每次時新創(chuàng)建一份,可以將其設置在構(gòu)造函數(shù)的原型上。
面向?qū)ο笥腥齻€特點,一個個來說:
封裝 私有變量利用閉包實現(xiàn)對象的私有變量。
function Animal (age) { this.getAge = function () { return age } } var dog = new Animal(3) console.log(dog.age) // undefined console.log(dog.getAge()) // 3
碰過的一個有趣的問題:
實現(xiàn)一個book構(gòu)造函數(shù),有一個屬性id,每次調(diào)用該值加1。
運用閉包和立刻執(zhí)行函數(shù)。
let Book = (function () { let id = 1 return function () { this.id = id++ } })() let bok1 = new Book() let bok2 = new Book() let bok3 = new Book() console.log(bok3.id) // 3共有方法
看下面的代碼可以發(fā)現(xiàn),getAge被重復創(chuàng)建了
var dog = new Animal(3) var cat = new Animal(5) console.log(dog.getAge === dog.getAge) // false
如果不想方法或者屬性在每次new時新創(chuàng)建一份,可以將其設置在構(gòu)造函數(shù)的原型prototype上。
Animal.prototype.feed = function () { console.log("feed") } console.log(dog.feed === cat.feed) // true繼承
聽說繼承有六種方法,假設讓Dog繼承Animal,無非就是for in 復制屬性,修改原型鏈如dog.prototype = new Animal,直接Object.create,在Dog中使用Animal.call
然而我們記住最好的一種就夠了,就是組合繼承。
先試下這樣寫,利用call的繼承:
function Animal (name) { this.name = name; this.say = function() { console.log(this.name) } } // *1 function Dog (color, name) { Animal.call(this, name) this.color = color } // *2 let wangcai = new Dog("blue", "wangcai") console.log(wangcai) // {color: "blue", name: "wangcai") wangcai.say() // "wangcal"
可是如果在*1處加上這樣的代碼
Animal.prototype.say2 = function() { console.log(this.name) }
在*3處輸入
wangcai.say2(),會報錯提示不存在該方法,說明我們的繼承是不完整的。dog沒有繼承原型鏈上的方法
我們需要在*2補上:
Dog.prototype = Object.create(Animal.prototype)
這時候不會報錯了,補上Object.create的polyfill
function objectCreate (proto) { function F() {} F.prototype = proto; return new F(); }
然而還有一點小漏洞,當我們查看wangcai.constructor時,會發(fā)現(xiàn)指向的是Animal。因此我們需要修復一下:
Dog.prototype.constructor = Dog
補充一下new的模擬
function fNew (base) { var o = {} o.__proto__ = base.prototype base.call(o) return o }
完整代碼
function Animal (name) { this.name = name; this.say = function() { console.log(this.name) } } Animal.prototype.say2 = function () { console.log(this.name) } function Dog (color, name) { Animal.call(this, name) this.color = color } Dog.prototype = Object.create(Animal.prototype) Dog.prototype.constructor = Dog let wangcai = new Dog("blue", "wangcai")
檢測繼承是否成功的代碼:
console.log(wangcai instanceof Animal) console.log(wangcai instanceof Dog) console.log(wangcai.constructor === Dog) console.log(wangcai.say2 === Animal.prototype.say2) console.log(wangcai.__proto__ === Dog.prototype) console.log(wangcai.__proto__.__proto__ === Animal.prototype) console.log(wangcai.__proto__.__proto__.__proto__ === Object.prototype) console.log(wangcai.constructor === Dog)
使用Object.create()和修復Dog.prototype.constructor = Dog是不是挺多余的?es6提供了這么一個函數(shù)Object.setPrototypeOf.
因此我們可以使用
Object.setPrototypeOf(Dog.prototype, Animal.prototype)
替換剛剛提到的兩行代碼
可以了解到Object.setPrototypeOf(A,B)相當于令A.__proto__ = B。
多態(tài)一個函數(shù)可以應用于不同的對象。并且根據(jù)this的不同,函數(shù)調(diào)用的結(jié)果也不同
function test() { alert([this.a, this.b]); } test.call({a: 10, b: 20}); // 10, 20 test.call({a: 100, b: 200}); // 100, 200 var a = 1; var b = 2; test(); // 1, 2
或是在函數(shù)中檢測arguments的數(shù)量和類型來實現(xiàn)多態(tài)
function add (a, b) { if (arguments.length === 2) { return a + b } else { return a + 1 } } console.log(add(1,4)) console.log(add(1))
END
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/95893.html
摘要:對于屬性來說類內(nèi)部的調(diào)用方式靜態(tài)屬性是類的屬性普通屬性是類具體實例化出的對象的屬性所以二者是完全不同的調(diào)用方式也非常不同靜態(tài)屬性靜態(tài)屬性名類名靜態(tài)屬性名普通屬性普通屬性名類外部的調(diào)用方式靜態(tài)屬性是類的屬性普通屬性是類具體實例化出的對象的屬 對于 屬性 來說 類內(nèi)部的調(diào)用方式 靜態(tài)屬性是類的屬性 普通屬性是類具體實例化出的對象的屬性 所以二者是完全不同的, 調(diào)用方式也非常不同 ...
摘要:面向?qū)ο笾饕R點小結(jié),基于構(gòu)造函數(shù)可以理解為通過即將創(chuàng)建的對象將類實例化給一個對象賦予屬性或者方法原型便于方法的重用與構(gòu)造函數(shù)模式相比,使用原型對象的好處是可以讓所有對象實例共享它所包含的屬性和方法。 JavaScript面向?qū)ο笾饕R點小結(jié),基于ECMAScript 5. 構(gòu)造函數(shù) function People(name){ //this可以理解為通過new即將創(chuàng)建...
摘要:參考鏈接面向?qū)ο缶幊棠P同F(xiàn)在的很多編程語言基本都具有面向?qū)ο蟮乃枷?,比如等等,而面向?qū)ο蟮闹饕枷雽ο?,類,繼承,封裝,多態(tài)比較容易理解,這里就不多多描述了。 前言 在我們的日常日發(fā)和學習生活中會常常遇到一些名詞,比如 命令式編程模型,聲明式編程模型,xxx語言是面向?qū)ο蟮牡鹊龋@個編程模型到處可見,但是始終搞不清是什么?什么語言又是什么編程模型,當你新接觸一門語言的時候,有些問題是需...
閱讀 2075·2021-11-23 09:51
閱讀 2217·2021-09-29 09:34
閱讀 3710·2021-09-22 15:50
閱讀 3569·2021-09-22 15:23
閱讀 2600·2019-08-30 15:55
閱讀 713·2019-08-30 15:53
閱讀 3084·2019-08-29 17:09
閱讀 2640·2019-08-29 13:57