摘要:面向?qū)ο笤兔嫦驅(qū)ο笙腴_一個車,你不需要自己去造一個車,只需要一把鑰匙,車對于你來說就是一個對象。使用構造函數(shù)模式和原型模式組合初學筆記,個人記錄備忘,如有謬誤,歡迎指正。
面向?qū)ο蟆⒃?/b> 面向?qū)ο?/b>
想開一個車,你不需要自己去造一個車,只需要一把鑰匙,車對于你來說就是一個"對象"。
在JavaScript中的"對象", 具有屬性,當屬性的值是一個函數(shù)時,那么此屬性就是這個對象的方法.訪問屬性的方式參考Object介紹
首先想到的是字面量創(chuàng)建對象,其次是創(chuàng)建一個對象實例,然后一次對對象屬性進行賦值.但是無論這兩種那個方法都有個缺點,當需要重復創(chuàng)建大量相同的對象時,產(chǎn)生大量代碼這是很不理想的,這時想到函數(shù)的一個功能就是講重復代碼進行簡化,以便多次使用,那么構造函數(shù)形式創(chuàng)建多個對象方式就是理想的選擇了.
什么是構造函數(shù)?function outPut() { console.log("hello") } function Person (name,age) { this.name2 = name; this.age2 = age; this.sayName = function () { console.log("this.name2") }; } var person2 = new person("Kangkang" , 20) // 分別調(diào)用
這里有幾點需要注意,首先是這個this是誰? new操作符有什么作用?
this指向的創(chuàng)建的實例,這里指的是 person2, 而new操作符可以創(chuàng)建一個對象實例.
使用new通過構造函數(shù)方式創(chuàng)建對象的實際包含的步驟有:創(chuàng)建一個新對象,
將構造函數(shù)的作用域賦給新對象,此時this已經(jīng)指向新對象,操作this等同操作新對象
執(zhí)行構造函數(shù)里的代碼
返回創(chuàng)建的新對象
如何檢測對象的類型? (檢測操作符右邊的函數(shù)原型是否存在于左邊的實例的原型鏈上)使用instanceof 操作符,返回布爾值.
p1 instanceof Person; p1 instanceof Object;
第二個檢測,無論是自己創(chuàng)建的構造函數(shù)對象還是字面量對象,均為true,因為他們均繼承自Object. 對于某個構造函數(shù)創(chuàng)建的實例當其構造函數(shù)的原型被改變后使用此操作符發(fā)現(xiàn)返回false ,原因在于在實例的原型鏈上構造函數(shù)的原型是舊的對象,不是新的對象,自然也就不對了。instanceof-MDN
那么對于構造函數(shù)創(chuàng)建的對象里的方法,每次創(chuàng)建實例時都要重新創(chuàng)建,如何解決?思路是將這個方法提到實例的外面去,如果是全局對象不就可以直接調(diào)用了嗎?可是全局函數(shù)對于封裝來說可沒好處,所以原型模式也就有了用處.
原型原型是定義能夠被對象實例所使用的屬性和函數(shù)的一種方式.原型的屬性會變成實例的屬性.
這段話不容易理解.一點點分析,對象的原型屬性(prototype)指向的是一個對象,對象里存的屬性和方法在對象實例后(即構造函數(shù)方法創(chuàng)建的新對象) 可以被實例對象訪問使用.
function Person() { } Person.prototype.name = "Kangkang" Person.prototype.age = 20 Person.prototype.sayName = function () { console.log(this.name) } var person1 = new Person() person1.sayName() // "Kangkang" var person2 = new Person() person2.sayName() //"Kangkang" console.log(person1.sayName == person2.sayName) //true var person3 = new Person() person3.name = "Mary" person3.sayName() //"Mary"
在函數(shù)創(chuàng)建的時候,prototype屬性就被創(chuàng)建出來了,通過構造函數(shù)生成的實例在瀏覽器下支持一個屬性__proto__ 查看prototype(原型里的對象)
如圖所示
顯示的是當一個實例在自己屬性中找不到相應的方法或者屬性時往上一層尋找的情況。
檢測某個屬性屬于實例還是原型:
person1.hasOwnProperty("name") 當這個屬性是實例的返回true,是原型的返回false
注意到在實例中重寫某個屬性會阻止訪問原型中的這個屬性,可是不會影響到原型中的屬性。
多帶帶操作的in操作符
使用這個操作符可以檢測某個屬性是否可以通過對象訪問,這也就指的是無論這個屬性是實例中的還是原型中的,要知道實例可以通過 __proto__ 訪問,由上圖可知
"name" in Person1 可以訪問返回true,否則返回false
這個操作符可以和上面的hasOwnperty() 結(jié)合使用判斷某個屬性是否存在且存在于哪里。
如何為原型添加屬性和方法?由上面介紹可知,通過Person.prototype.name = "kangkang"
這種方法甚是繁瑣,多個屬性、方法將會導致反復的輸入,所以對象字面量的書寫方式就能很好解決這個問題。
function Person () { } Person.prototype = { name : "Kangkang", age: 20, job: "student", sayName = function() { console.log(name) } }防止實例與原型的鏈斷開
謹慎在初始化原型后再將其改變?yōu)榱硗庖粋€對象
function Person () { } var friend = new Person() Person.prototype.sayHi = function() { console.log("hi") } friend.sayHI(); // 在創(chuàng)建對象后再對原型添加方法依然有效
下面這種情況:
function Person () { } var friend = new Person() Person.prototype = { name : "Kangkang", age: 20, job: "student", friends: ["xiaojun","xiaoming"], sayName : function() { console.log(name) } friend.sayName();// error
這種情況相當于在原型初始化后又重新生成對象并且賦值,而原來的實例是指向初始化時的對象地址,故無法訪問新的原型里的屬性和方法.
原型對象和屬性的區(qū)別?如下程序:
function Person () { } Person.prototype = { name : "Kangkang", age: 20, job: "student", friends: ["xiaojun","xiaoming"], sayName : function() { console.log(name) } } var person6 = new Person() var person7 = new Person() // person6.name = "Mary" // console.log(person6.name) // console.log(person7.name) // person6.sayName = function() { // console.log("hi") // } person6.friends.push("xiaohong") console.log(person6.friends) console.log(person7.friends) console.log(person6.sayName == person7.sayName)
由上面的代碼得出:
當對原型中基本類型值屬性和方法在實例中重新添加會阻止尋找到原型中的屬性和方法,當用delete 操作符刪除后依然可以找到原型中的屬性和方法,也就是說在實例中重定義這兩種情況不會影響原型中的屬性和方法,但是如果原型中的屬性對應的值是引用類型,由于引用類型的特性,實例得到了相同的這個屬性的地址,又由于原型是實例公用的方法,所以當任一實例操作這個引用值屬性時都會影響到其他這個對象的實例。所以組合使用構造函數(shù)和原型也就很好解決這個問題。
使用構造函數(shù)模式和原型模式組合function Person (name, age, job) { this.name = name this.age = age this.job = job this.friends = ["kangkang","mary"] } Person.prototype = { constructor : Person, sayName : function () { console.log(this.name) } } var person1 = new Person("xiaojun",22,"student") var person2 = new Person("xiaowang", 21, "student") person1.friends.push("xiaozhang") console.log(person1.friends) // ["kangkang", "mary", "xiaozhang"] console.log(person2.friends) // ["kangkang", "mary"] console.log(person1.friends === person2.friends) //false console.log(person1.sayName === person2.sayName) //true
初學筆記,個人記錄備忘,如有謬誤,歡迎指正。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/94358.html
摘要:抽象類和接口小記抽象類和接口實現(xiàn)了的多態(tài)多態(tài)是面向?qū)ο蟪绦蛘Z言的核心在項目開發(fā)過程中其實很少使用抽象類接口用得比較多今天小記一下抽象類和接口的區(qū)別抽象類抽象類不能被實例化抽象類可以繼承可以定義變量可以定義構造方法抽象方法的要顯式的寫出來其子 Java抽象類和接口小記 Java抽象類和接口實現(xiàn)了java的多態(tài).多態(tài)是面向?qū)ο蟪绦蛘Z言的核心,在項目開發(fā)過程中,其實很少使用抽象類,接口用得比...
摘要:前言最近將公司項目的從版本升到了版本,跟完全不兼容,是一次徹底的重寫。升級過程中踩了不少的坑,也有一些值得分享的點。沒有就會匹配所有路由最后不得不說升級很困難,坑也很多。 前言 最近將公司項目的 react-router 從 v3 版本升到了 v4 版本,react-router v4 跟 v3 完全不兼容,是一次徹底的重寫。這也給升級造成了極大的困難,與其說升級不如說是對 route...
摘要:以上的描述說,此方法有兩個參數(shù),新創(chuàng)建對象的原型對象。創(chuàng)建一個干凈的對象,我們就要借助上面的這個方法了是基本數(shù)據(jù)類型,是沒有原型的,所以講作為第一個參數(shù)傳入創(chuàng)建出來的對象就是干凈的對象。這個對象不會繼承任何。 什么叫干凈的map 一般聲明一個map對象我們使用字面量的方法 let map = {}; 我們知道,使用字面量聲明的對象其實就是默認繼承了Object對象,也就是說這個對象擁有...
閱讀 1628·2021-09-08 10:42
閱讀 3611·2021-08-11 10:23
閱讀 3982·2019-08-30 14:10
閱讀 2740·2019-08-29 17:29
閱讀 3097·2019-08-29 12:50
閱讀 647·2019-08-26 13:36
閱讀 3463·2019-08-26 11:59
閱讀 1494·2019-08-23 16:23