成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

面向?qū)ο蟮男【啪?

時(shí)飛 / 3097人閱讀

摘要:由構(gòu)造函數(shù)返回的對(duì)象就是表達(dá)式的結(jié)果。如果構(gòu)造函數(shù)沒有顯式返回一個(gè)對(duì)象,則使用步驟創(chuàng)建的對(duì)象。運(yùn)算符返回一個(gè)布爾值,表示對(duì)象是否為某個(gè)構(gòu)造函數(shù)的實(shí)例。

面向?qū)ο?/b>

本人能力有限,有誤請(qǐng)斧正

本文旨在復(fù)習(xí)面向?qū)ο?不包含es6)

本文學(xué)習(xí)思維

創(chuàng)建對(duì)象的方式,獲取對(duì)象屬性

構(gòu)造函數(shù),構(gòu)造函數(shù)的new 做了什么

原型與原型對(duì)象

原型鏈

繼承(借用構(gòu)造繼承、原型繼承、組合繼承、寄生組合繼承)

獲取對(duì)象屬性的三個(gè)方法

for...in..

Object.keys() ie9以上放心使用

keys的支持

Object.getOwnPeropertyNames 會(huì)把所有屬性枚舉出來(lái)(如數(shù)組的length)

創(chuàng)建對(duì)象的方法

字面量 var o = {};

構(gòu)造函數(shù) var o = new Object()

Object.create() var o = Object.create( )

object.create()有兩個(gè)參數(shù)第一個(gè)是要新創(chuàng)建對(duì)象的原型對(duì)象, 第二個(gè)可選:自己定義的屬性,需要配置麻煩一般不用,返回一個(gè)新對(duì)象,帶著指定的原型對(duì)象和屬性

通過給Object.create()參數(shù)傳null可以獲得一個(gè)純凈的沒有原型的對(duì)象。原因是null是原型鏈的鏈末

輸出查看原型鏈發(fā)現(xiàn)create在創(chuàng)造一個(gè)對(duì)象會(huì)存在傳入的屬性與方法
這個(gè)方法太適合繼承了,他會(huì)直接繼承傳入的屬性和方法
通過測(cè)試傳入{}時(shí),也會(huì)存在Object.__proto__ 指向 Object.__proto__;

// Object.create() 實(shí)現(xiàn)方式 
// 實(shí)際這個(gè)是原型式繼承的核心
var object = function(proto){
    var F = function(){}; // 創(chuàng)建一個(gè)對(duì)象
    F.prototype = proto; //變量原型指向傳入對(duì)象
    return new F();
}
構(gòu)造函數(shù)、實(shí)例、原型、原型鏈

參考資料:MDN-繼承與原型鏈

構(gòu)造函數(shù):

是一個(gè)函數(shù)

首字母大寫

使用new關(guān)鍵字創(chuàng)建

構(gòu)造函數(shù)(函數(shù)聲明或者函數(shù)表達(dá)式)本質(zhì)還是函數(shù),只是用來(lái)創(chuàng)建對(duì)象,還有個(gè)慣例就是首字母大寫

// 構(gòu)造函數(shù)
function Person(){}
// 調(diào)用構(gòu)造函數(shù),創(chuàng)建對(duì)象
var p1 = new Person();
為什么說(shuō)構(gòu)造函數(shù)特殊呢,首先聊聊new關(guān)鍵字

參考:

MDN-new運(yùn)算符

高程3--p145

阮一峰博客

通過new關(guān)鍵字可以創(chuàng)建新對(duì)象!

在new一個(gè)對(duì)象的時(shí)候做了什么事?4個(gè)步驟(高程3)

創(chuàng)建一個(gè)新對(duì)象

將構(gòu)造函數(shù)的作用域賦給新對(duì)象 (因此this就指向了這個(gè)新對(duì)象)

執(zhí)行構(gòu)造函數(shù)中的代碼(為這個(gè)新對(duì)象添加屬性)

返回新對(duì)象(如果構(gòu)造函數(shù)中返回了其他對(duì)象,則返回其他對(duì)象)

MDN簡(jiǎn)化版,只討論過程,無(wú)法傳參
    // MND簡(jiǎn)化
    
    /*
    一個(gè)繼承自 Foo.prototype 的新對(duì)象被創(chuàng)建。
    
    使用指定的參數(shù)調(diào)用構(gòu)造函數(shù) Foo ,并將 this 綁定到新創(chuàng)建的對(duì)象。
    new Foo 等同于 new Foo(),也就是沒有指定參數(shù)列表,F(xiàn)oo 不帶任何參數(shù)調(diào)用的情況。
    
    由構(gòu)造函數(shù)返回的對(duì)象就是 new 表達(dá)式的結(jié)果。如果構(gòu)造函數(shù)沒有顯式返回一個(gè)對(duì)象,則使用步驟1創(chuàng)建的對(duì)象。
    (一般情況下,構(gòu)造函數(shù)不返回值,但是用戶可以選擇主動(dòng)返回對(duì)象,來(lái)覆蓋正常的對(duì)象創(chuàng)建步驟)
    */
    
    var Foo = function(){};
    var _new2 = function(fn){
        var o = Object.create(fn.prototype);
        var k = fn.call(o);
        if(typeof k === "object"){
            return k;
        }else{
            return o;
        }
    }
    var f = _new2(Foo);

阮老師的版本可以傳參,而且很詳細(xì)了
    function _new(/* 構(gòu)造函數(shù) */ constructor, /* 構(gòu)造函數(shù)參數(shù) */ params) {
      // 將 arguments 對(duì)象轉(zhuǎn)為數(shù)組
      var args = [].slice.call(arguments);
      // 取出構(gòu)造函數(shù)
      var constructor = args.shift();
      // 創(chuàng)建一個(gè)空對(duì)象,繼承構(gòu)造函數(shù)的 prototype 屬性
      var context = Object.create(constructor.prototype);
      // 執(zhí)行構(gòu)造函數(shù)
      var result = constructor.apply(context, args);
      // 如果返回結(jié)果是對(duì)象,就直接返回,否則返回 context 對(duì)象
      return (typeof result === "object" && result != null) ? result : context;
    }

    // 實(shí)例
    var actor = _new(Person, "張三", 28);
實(shí)例是什么
構(gòu)造函數(shù)是對(duì)一個(gè)對(duì)象的抽象描述,實(shí)例則是對(duì)象的具體表現(xiàn)
原型對(duì)象(prototype)

好吧!大boss出場(chǎng),都說(shuō)javaScript最具有特色的就是原型

參考:

高程3 --p147

原型是什么?(高程3)

我們創(chuàng)建的每個(gè)函數(shù)都有一個(gè)prototype(原型) 屬性,這個(gè)屬性是一個(gè)指針,指向一個(gè)對(duì)象

函數(shù)的屬性

原型指向一個(gè)對(duì)象

理解原型對(duì)象 高程3 -- p148有興趣可以去讀一下

無(wú)論什么時(shí)候只要?jiǎng)?chuàng)建了一個(gè)新函數(shù),就會(huì)根據(jù)一組特定的規(guī)則為該函數(shù)創(chuàng)建一個(gè)prototype屬性,這個(gè)屬性將指向函數(shù)的原型對(duì)象。在默認(rèn)情況下,所有的原型對(duì)象會(huì)自動(dòng)獲得一個(gè)constructor(構(gòu)造函數(shù))屬性,這個(gè)屬性包含一個(gè)指向prototype屬性所有函數(shù)的指針。通過這個(gè)構(gòu)造函數(shù),我們還可以繼續(xù)為原型對(duì)象添加其他屬性和方法

按照書上的理解:

簡(jiǎn)述:([[Prototype]] === __proto__

所有構(gòu)造函數(shù)有一個(gè)屬性指向原型對(duì)象(prototype)

所有由構(gòu)造器生成的實(shí)例對(duì)象中有個(gè)__poroto__指向原型對(duì)象

原型對(duì)象中都有一個(gè)constructor的屬性,指向構(gòu)造函數(shù)

        var Person = function() {};
        Person.prototype.age = 1;
        var p = new Person();
        var p2 = new Person();
        console.log(p.__proto__ === Person.prototype); // true
        console.log(p2.__proto__ === Person.prototype); // true
        console.log(Person === Person.prototype.constructor); // true
原型鏈

原型鏈就是在查找到某個(gè)屬性或者方法不斷向上查找的一個(gè)過程

MDN-非常具有代表的簡(jiǎn)化原型鏈

// 讓我們假設(shè)我們有一個(gè)對(duì)象 o, 其有自己的屬性 a 和 b:
// {a: 1, b: 2}
// o 的 [[Prototype]] 有屬性 b 和 c:
// {b: 3, c: 4}
// 最后, o.[[Prototype]].[[Prototype]] 是 null.
// 這就是原型鏈的末尾,即 null,
// 根據(jù)定義,null 沒有[[Prototype]].
// 綜上,整個(gè)原型鏈如下: 
// {a:1, b:2} ---> {b:3, c:4} ---> null

console.log(o.a); // 1
// a是o的自身屬性嗎?是的,該屬性的值為1

console.log(o.b); // 2
// b是o的自身屬性嗎?是的,該屬性的值為2
// 原型上也有一個(gè)"b"屬性,但是它不會(huì)被訪問到.這種情況稱為"屬性遮蔽 (property shadowing)"

console.log(o.c); // 4
// c是o的自身屬性嗎?不是,那看看原型上有沒有
// c是o.[[Prototype]]的屬性嗎?是的,該屬性的值為4

console.log(o.d); // undefined
// d是o的自身屬性嗎?不是,那看看原型上有沒有
// d是o.[[Prototype]]的屬性嗎?不是,那看看它的原型上有沒有
// o.[[Prototype]].[[Prototype]] 為 null,停止搜索
// 沒有d屬性,返回undefined

再用對(duì)象表示一個(gè)

// 屬性遮蔽
function Person() {
    this.name = "111";
}
Person.prototype.name = "222";

var p1 = new Person();
console.log(p1.name); // 111
console.log(p1.__proto__.name); // 222


var p2  = new Person();
console.log(p2.age);

現(xiàn)在要查找p2.age屬性

實(shí)例對(duì)象中有沒有?沒有

實(shí)例對(duì)象通過__prope__找到原型對(duì)象,原型對(duì)象中有么?沒有

找到Object的原型中查找有么?沒

找到null這個(gè)對(duì)象,作為作用域的鏈末,也沒有,這個(gè)值就是undefined

屬性屏蔽就是找到了就不會(huì)再找了(實(shí)例上的屬性>原型鏈上的屬性),實(shí)際還是存在

幾種能遇到的操作符

in操作符

isPrototypeOf()

Object.getPrototypeOf()

instanceof (對(duì)象)

typeof

in操作符
如果指定的屬性在指定的對(duì)象或其原型鏈中,則in 運(yùn)算符返回true。語(yǔ)法:prop in object
isPrototypeOf()
isPrototypeOf() 方法用于測(cè)試一個(gè)對(duì)象是否存在于另一個(gè)對(duì)象的原型鏈上。
function Foo() {}
function Bar() {}
function Baz() {}

Bar.prototype = Object.create(Foo.prototype);
Baz.prototype = Object.create(Bar.prototype);

var baz = new Baz();

console.log(Baz.prototype.isPrototypeOf(baz)); // true
console.log(Bar.prototype.isPrototypeOf(baz)); // true
console.log(Foo.prototype.isPrototypeOf(baz)); // true
console.log(Object.prototype.isPrototypeOf(baz)); // true
instanceof運(yùn)算符返回一個(gè)布爾值,表示對(duì)象是否為某個(gè)構(gòu)造函數(shù)的實(shí)例。
instanceof的原理是檢查右邊構(gòu)造函數(shù)的prototype屬性,是否在左邊對(duì)象的原型鏈上。(判斷他們的地址指向是否一致)。有一種特殊情況,就是左邊對(duì)象的原型鏈上,只有null對(duì)象。這時(shí),instanceof判斷會(huì)失真。

幾點(diǎn)instanceof的注意

用于對(duì)象(由于instanceof的原理)

與null有關(guān)要注意

//instanceof判斷會(huì)失真
var obj = Object.create(null);
typeof obj // "object"
Object.create(null) instanceof Object // false


//null作為一個(gè)特殊的Object卻不屬于Object創(chuàng)建的實(shí)例,null原型鏈的鏈末
undefined instanceof Object // false
null instanceof Object // false

// instanceof 用于對(duì)象
var str = "1"
var str2 = new String("2");
str instanceof String // false
str2 instanceof String // true
typeof
typeof 1 //number
typeof "" // string
typeof undefined //undefined
typeof true // boolean
typeof function(){} // function
typeof {}  // object
typeof []  // object
typeof null // object
typeof Symbol() //symbol ES6
繼承:

繼承有幾種

我用我總結(jié)了一些思維導(dǎo)圖

創(chuàng)建對(duì)象

繼承的優(yōu)缺點(diǎn)

這里把繼承的幾種方式羅列出來(lái)方便查閱,以下大多是代碼,簡(jiǎn)易的我總結(jié)在思維導(dǎo)圖中了

1.原型(鏈)繼承

關(guān)鍵點(diǎn)是要打通原型鏈
由于原型對(duì)象是函數(shù)初次創(chuàng)建就會(huì)存在的對(duì)象,所以會(huì)共享
共享就會(huì)存在共享問題

優(yōu)點(diǎn):

共享屬性與方法

可以通過instanceof來(lái)判斷關(guān)系

缺點(diǎn):

共享問題

不能傳遞參數(shù)

        // 父類
        function SuperType() {
            this.property = true;
        }
        SuperType.prototype.getSuperValue = function () {
            return this.property;
        }
        
        // 子類
        function SubType() {
            this.subproperty = false;
        }
        // 繼承父類 打通原型鏈
        SubType.prototype = new SuperType();
        SubType.prototype.getSubValue = function () {
            return this.subproperty;
        }
        
        var instance = new SubType();
        console.log(instance.getSuperValue()); // true
借用構(gòu)造函數(shù)

關(guān)鍵在于環(huán)境變量(this)的指向,由于每次創(chuàng)建都會(huì)創(chuàng)建一個(gè)新的this所以會(huì)擁有自己的屬性與方法,由于是改變this指向所以無(wú)法共享原型對(duì)象

優(yōu)點(diǎn):

私有屬性與方法

可以傳參數(shù)

缺點(diǎn):

引用類型,重復(fù)創(chuàng)建,冗余浪費(fèi)內(nèi)存

無(wú)法共享

無(wú)法判斷關(guān)系

        // 父類
        function SuperType() {
            this.colors = ["red"];
        }
        // 子類
        function SubType() {
            // 繼承父類
            SuperType.call(this);
        }
        var instance1 = new SubType();
        colors.push("black");
        cosnole.log(instance1.colors); // red,black
        var instance2 = new SubType();
        console.log(instance2.colors); // red
組合式繼承

組合了原型繼承與借用構(gòu)造函數(shù)繼承繼承了優(yōu)點(diǎn),但是由于組合,所以創(chuàng)建了兩次對(duì)象,造成輕微的浪費(fèi)空間

優(yōu)點(diǎn):

私有屬性和方法

共享屬性與方法

可以確認(rèn)實(shí)例與構(gòu)造函數(shù)之間的關(guān)系

缺點(diǎn)

造成內(nèi)存的冗余浪費(fèi)

        // 父類
        function SuperType(name) {
            this.name = name;
            this.colors = ["red"];
        }
        SuperType.prototype.sayName = function () {
            console.log(this.name);
        }
        // 子類
        function SubType(name, age) {
            // 繼承屬性
            SuperType.call(this, name);
            this.age = age;
        }
        // 繼承方法
        SubType.prototype = new SuperType();
        SubType.prototype.sayAge = function () {
            console.log(this.age);
        }
        var instance1 = new SubType("name1", 1);
        instance1.colors.push("black");
        console.log(instance1.colors); // red,black
        instance1.sayName(); // name1
        instance1.sayAge(); // 1

        var instance2 = new SubType("name2", 2);
        console.log(instance2.colors); // red
        instance2.sayName(); // name2
        instance2.sayAge(); // 2
寄生組合繼承

寄生組合繼承是把原型繼承給改掉,實(shí)際上就是想要父級(jí)的原型鏈,不一定要?jiǎng)?chuàng)建對(duì)象所以有了寄生組合繼承,該繼承是目前最完善的繼承方式

        // 寄生繼承
        function inheritPrototype(subType, superType) {
            var prototype = Object.create(superType.prototype);
            prototype.constructor = subType;
            subType.prototype = prototype;
        }
        // 父類
        function SuperType(name) {
            this.name = name;
            this.colors = ["red"];
        }
        SuperType.prototype.sayName = function () {
            console.log(this.name);
        }    
        // 子類繼承
        function SubType(name, age) {
            SuperType.call(this, name);    
        }
        inheritPrototype(SubType, SuperType);
        SubType.prototype.sayAge = function () {
            console.log(this.age)
        }
參考資料:

MDN-對(duì)象

冴羽的博客

阮一峰的網(wǎng)絡(luò)日志

javaScript高級(jí)程序設(shè)計(jì)第三版

阮一峰的網(wǎng)絡(luò)日志:

Javascript繼承機(jī)制的設(shè)計(jì)思想

Javascript 面向?qū)ο缶幊蹋ㄒ唬悍庋b

Javascript面向?qū)ο缶幊蹋ǘ簶?gòu)造函數(shù)的繼承

Javascript面向?qū)ο缶幊蹋ㄈ悍菢?gòu)造函數(shù)的繼承

《JavaScript 標(biāo)準(zhǔn)參考教程(alpha)》,by 阮一峰

看了高程3與阮一峰老師的博客,結(jié)合起來(lái)更加好理解

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/95686.html

相關(guān)文章

  • 從零開始單排學(xué)設(shè)計(jì)模式「UML類圖」定級(jí)賽

    摘要:從零開始單排學(xué)設(shè)計(jì)模式的國(guó)服排位之旅,今天正式開啟目前段位定級(jí)賽這篇文章來(lái)總結(jié)下類圖,本來(lái)不打算講類圖的,因?yàn)槲以趯W(xué)習(xí)設(shè)計(jì)模式的時(shí)候,一遇到有關(guān)的就會(huì)自動(dòng)忽略,一看感覺就很復(fù)雜。關(guān)聯(lián)關(guān)系用實(shí)現(xiàn)箭頭來(lái)表示。 閱讀本文大概需要 3.5 分鐘。 本篇是設(shè)計(jì)模式系列的開篇,雖然之前也寫過相應(yīng)的文章,但是因?yàn)榉N種原因后來(lái)斷掉了,而且發(fā)現(xiàn)之前寫的內(nèi)容也很渣,不夠系統(tǒng)。 所以現(xiàn)在打算重寫,加上距離現(xiàn)...

    Loong_T 評(píng)論0 收藏0
  • (void 0)與undefined之間九九

    摘要:又是啥是原始類型值之一,也是全局對(duì)象的屬性,在部分低級(jí)別的瀏覽器中可以被修改,在局部作用域中也可以被修改。所以常見的解決方法是在這個(gè)問題中提到用去替代標(biāo)簽的空屬性會(huì)減少頁(yè)面請(qǐng)求是否屬實(shí)有待考證結(jié)尾第一篇暫時(shí)寫完了,歡迎大家吐槽和提意見。 前言 原文鏈接 源碼地址 這是underscore.js源碼分析的第一篇文章,為什么選擇寫這篇文章呢?其實(shí)主要有兩點(diǎn) 下劃線源碼中通篇可見這樣的判斷...

    novo 評(píng)論0 收藏0
  • (void 0)與undefined之間九九

    摘要:又是啥是原始類型值之一,也是全局對(duì)象的屬性,在部分低級(jí)別的瀏覽器中可以被修改,在局部作用域中也可以被修改。所以常見的解決方法是在這個(gè)問題中提到用去替代標(biāo)簽的空屬性會(huì)減少頁(yè)面請(qǐng)求是否屬實(shí)有待考證結(jié)尾第一篇暫時(shí)寫完了,歡迎大家吐槽和提意見。 前言 原文鏈接 源碼地址 這是underscore.js源碼分析的第一篇文章,為什么選擇寫這篇文章呢?其實(shí)主要有兩點(diǎn) 下劃線源碼中通篇可見這樣的判斷...

    Arno 評(píng)論0 收藏0
  • 每日 30 秒 ? img の 九九

    showImg(https://raw.githubusercontent.com/pushmetop/resource/master/30-seconds-for-everyday/img-tag/poster.png); 簡(jiǎn)介 SEO、跨域、無(wú)障礙閱讀、事件、圖片標(biāo)簽 小九九 最直接的聯(lián)想便是 九九乘法表,但是 小九九 也用在形容一個(gè)人在心里打著算盤 小主意 和 小秘密。小秘密已經(jīng)被 H1 の...

    lolomaco 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<