JS對象---奧義:真の由淺入深

This is my first blood!javascript

第一次在segmentfault上寫(chao)文章。java

內容提要:認(wu)真(liao)的整理一下javascript對象的知識,人家仍是菜鳥,必需要搞懂啊。segmentfault

PS:
1.真的菜,因此看到文章的同窗,推薦採用隨緣閱讀法,請自行忽略裏面充斥大量的,哦不,巨量的錯誤、bug。
2.若是您願意指出個人錯誤,那最好不過了,寡人謝謝!(參見文章中的‘求大腿’的字樣)
3.不過,若是你期望以此契機,期待一場與程序媛之間的轟轟烈烈的深入的交互,那您仍是繞道而行吧。哥真的是漢子,不是童瑤。
4.說是筆記,大部分的代碼都是copy的,不爽的同窗,直接看參考資料吧。數組


一 參考資料

1.MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects
2.文檔:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Objectapp

二 全都是對象

在 JavaScript 中,幾乎全部的東西都是對象。全部的原生類型除了 null 與 undefined 以外都被看成對象。它們能夠被賦予屬性(某些類型的被賦予的屬性不能被持久化),而且它們都有對象的所有特徵。dom

三 建立對象

兩種建立方式:ide

1.對象初始化器(Object Initializer)建立對象。(容易理解)
2.建立一個構造函數並使用該函數和 new 操做符初始化對象。(容易裝逼)函數

容易理解的建立方式

模版:ui

var obj = { property_1:   value_1,   // property_# may be an identifier...
                2:            value_2,   // or a number...
                // ...,
                "property n": value_n }; // or a string

實例:this

var lolhero = new Object();
lolhero.basicSkill = "Q、W、E";
lolhero.bigSkill = "R only";
lolhero.commotSkill = "D&F";

//兩種訪問方式
console.log(lolhero['basicSkill']);//採用相似關聯數組的方式訪問
console.log(lolhero.basicSkill);//直接訪問

容易裝逼的建立方式

使用構造函數,須要兩步!!!

  • 經過建立一個構造函數來定義對象的類型。首字母大寫是很是廣泛並且很恰當的慣用法。

  • 經過 new 建立對象實例。

寫的太好直接copy過來了

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}

var Car = new Car("Eagle", "Talon TSi", 1993);
var kenscar = new Car("Nissan", "300ZX", 1992);
var vpgscar = new Car("Mazda", "Miata", 1990);

一個對象的屬性值能夠是另外一個對象。例如,假設你按以下方式定義了 person 對象:

function Person(name, age, sex) {
  this.name = name;
  this.age = age;
  this.sex = sex;
}

而後按以下方式建立了兩個 person 實例:

var rand = new Person("Rand McKinnon", 33, "M");
    var ken = new Person("Ken Jones", 39, "M");

那麼,你能夠重寫 car 的定義以包含一個擁有它的 owner 屬性,如:

function Car(make, model, year, owner) {
        this.make = make;
        this.model = model;
        this.year = year;
        this.owner = owner;
    }

你能夠按以下方式建立新對象:

var car1 = new Car("Eagle", "Talon TSi", 1993, rand);
    var car2 = new Car("Nissan", "300ZX", 1992, ken);

注意在建立新對象時,上面的語句將 rand 和 ken 做爲 owner 的參數值,而不是傳入字符串字面量或整數值。接下來你若是想找出 car2 的擁有者的姓名,你能夠訪問以下屬性:

car2.owner.name

注意你老是能夠爲以前定義的對象增長新的屬性。例如,語句

car1.color = "black";

爲 car1 增長了 color 屬性,並將其值設爲 "black." 然而,這並不影響其餘的對象。想要爲某個類型的全部對象增長新屬性,你必須將屬性加入到 car 對象類型的定義中。

PS:發現沒,雖然第二種建立對象的方式看起來不那麼天然.
可是卻好用,容易移植,容易從新定義,容易複用。因此,仍是裝逼好啊!

Object.create 建立對象

感受挺麻煩的,反正已經有了其餘建立方式,暫且無論他了。

(這玩意兒通常用的多嗎?多用來處理什麼功能?求大腿

四 屬性

若是對象的屬性名千奇百怪怎麼辦?

這樣也是容許的(太難爲js了吧),有誰這麼變態的用各類類型的屬性名,算了,變態老是有的。

var myObj = new Object(),
    str = "myString",
    rand = Math.random(),
    obj = new Object();

    myObj.type              = "Dot syntax";
    myObj["date created"]   = "String with space";
    myObj[str]              = "String value";
    myObj[rand]             = "Random Number";
    myObj[obj]              = "Object";
    myObj[""]               = "Even an empty string";

    console.log(myObj);

固然了,屬性值,也能夠是個變量

var propertyName = "make";
    myCar[propertyName] = "Ford";

    propertyName = "model";
    myCar[propertyName] = "Mustang";

對象的屬性太多,用for(var i in obj){}來遍歷它

hasOwnProperty: 若是 object 具備指定名稱的屬性,那麼JavaScript中hasOwnProperty函數方法返回 true;反之則返回 false。此方法沒法檢查該對象的原型鏈中是否具備該屬性;該屬性必須是對象自己的一個成員。

function showProps(obj,objName) {
        var result = "";
        for(var i in obj){
            if( obj.hasOwnProperty(i) ) {
                result += objName+"."+i+" = "+obj[i]+"\n";
            }
        }
        return result;
    }

    console.log(showProps(myObj,"myobj"));

從 ECMAScript 5 開始,有三種原生的方法用於列出或枚舉對象的屬性:

for...in 循環
該方法依次訪問一個對象及其原型鏈中全部可枚舉的屬性。

Object.keys(o)
該方法返回一個對象 o 自身包含(不包括原型中)的全部屬性的名稱的數組。

Object.getOwnPropertyNames(o)
該方法返回一個數組,它包含了對象 o 全部擁有的屬性(不管是否可枚舉)的名稱。

在 ECMAScript 5 中,沒有原生的方法枚舉一個對象的全部屬性。然而,能夠經過如下函數完成:

function listAllProperties(o){
        var objectToInspect;
        var result = [];

        for(objectToInspect = o; objectToInspect !== null; objectToInspect = Object.getPrototypeOf(objectToInspect)){
            result = result.concat(Object.getOwnPropertyNames(objectToInspect));
        }

        return result;
    }

上面的這個方法,能夠訪問全部的可枚舉和不可枚舉的屬性。

PS:對象裏面的屬性有可枚舉和不可枚舉兩種。(不甚理解什麼是不可枚舉,求大腿!)

五 繼承

全部的 JavaScript 對象繼承於至少一個對象。被繼承的對象被稱做原型,而且繼承的屬性可能經過構造函數的 prototype 對象找到。

六 爲對象類型定義屬性

你能夠經過 prototype 屬性爲以前定義的對象類型增長屬性。這爲該類型的全部對象,而不是僅僅一個對象增長了一個屬性。下面的代碼爲全部類型爲 car 的對象增長了 color 屬性,而後爲對象 car1 的 color 屬性賦值:

Car.prototype.color = null;
car1.color = "black";

七 若是我想給對象添加方法怎麼辦?

兩種方式:

objectName.methodname = function_name;
var myObj = {
    myMethod: function(params) {
        // ...do something
    }
};

前面建立對象的完整寫法:

function Car(make, model, year, owner) {

        //注意displayCar函數裏面this和外面的this指向的是同一個car對象!
        function displayCar() {
            console.log("this2",this);
            var result = "A Beautiful " + this.year + " "
            + this.make + " " + this.model;
            return result;
        }

        this.make = make;
        this.model = model;
        this.year = year;
        this.owner = owner;
        console.log("this1",this);
        this.displayCar = displayCar;
    }

    var car = new Car("福特汽車","奔馳",1234,"maomaoliang");
    console.log(car.displayCar());

或者

function Car(make, model, year, owner) {
    this.make = make;
    this.model = model;
    this.year = year;
    this.owner = owner;
    this.displayCar = function(){
        //...
    };
}

八 刪除屬性

用 delete 操做符刪除一個不是繼承而來的屬性。下面的例子說明如何刪除一個屬性:

//Creates a new object, myobj, with two properties, a and b.
var myobj = new Object;
myobj.a = 5;
myobj.b = 12;

//Removes the a property, leaving myobj with only the b property.
delete myobj.a;

九 比較對象

在 JavaScript 中 objects 是一個引用類型。將兩個引用相同的對象想比較會返回 true; 將兩個方法和屬性相同的對象相比較,會返回 false;

// fruit object reference variable
var fruit = {name: "apple"};

// fruitbear object reference variable
var fruitbear = {name: "apple"};

fruit == fruitbear // return false

fruit === fruitbear // return false
// fruit object reference variable
var fruit = {name: "apple"};

// fruitbear object reference variable
var fruitbear = fruit;  // assign fruit object reference to fruitbear object reference variable

// here fruit and fruitbear pointing to same object called fruit
fruit == fruitbear // return true

// here fruit and fruitbear pointing to same object called fruit
fruit === fruitbear // return true

意思就是,用的時候要比較引用,而不是比較所有咯?求大腿

相關文章
相關標籤/搜索