Objects 物件

每個變數可以表現像 JavaScript 物件,除了 null 和 undefined。

false.toString(); // 'false'
[1, 2, 3].toString(); // '1,2,3'

function Foo(){}
Foo.bar = 1;
Foo.bar; // 1

[Objects的使用與屬性]

刪除屬性(delete)

唯一刪除屬性的方式就是用 delete 操作符。

設置屬性為 undefined 或是 null 只有刪除的屬性和值的關聯,沒有真的刪掉屬性

測試方法如下

var obj = {
    bar: 1,
    foo: 2,
    baz: 3
};
obj.bar = undefined;
obj.foo = null;
delete obj.baz;

for(var i in obj) {
    if (obj.hasOwnProperty(i)) {
        console.log('var '+ i, '=> ' + obj[i]);
    }
}
//"var bar" "=> undefined"
//"var foo" "=> null"

執行後發現除了baz外,其他變數都還存在

Accessing Properties (訪問屬性 )

物件在呼叫的時候有兩種方式,點操作或是中括號操作

var foo = {name: 'kitten'}
foo.name; // kitten
foo['name']; // kitten

兩種語法是相等的,唯一的差別是,使用中括號允許你動態的設定屬性,使用點操作不允許屬性為變數,否則會造成語法錯誤

var get = 'name';
foo[get]; // kitten

foo.1234; // SyntaxError
foo['1234']; // works

Notation of Keys(屬性名的語法) => string literal

物件的屬性名可以使用字符串或是普通的宣告。

var test = {
    'case': 'I am a keyword, so I must be notated as a string', //建議使用
    delete: 'I am a keyword, so me too' // raises SyntaxError
};

這是由於 JavaScript 編譯器在 ECMAScript 5之前都會拋出 SyntaxError 的錯誤。 這個錯誤的原因是 delete 是 JavaScript 語言的一個 關鍵字(某個函式) 因此為了在更低的版本能執行最好用 string literal


[Prototype]

JavaScript 使用的是原型模型。不包含原本繼承的模型。 下面的例子中,物件 Test 會繼承來自 Bar.prototype 和 Foo.prototype。

因此它可以進入來自 Foo 原型的方法 method。 同時它也可以訪問 那個 定義在原型上的 Foo 實例屬性 call。

要注意的是 new Bar() 沒有 創立一個新的 Foo 實例,它重複利用的原本的 prototype。 因此, Bar 的實例會分享到 相同 的 private_key 屬性。

function Foo(){
  this.private_key = 'private key';
}
Foo.prototype = {
  'key' : 'foo',
  'call' : function(){
    console.log('Call Foo Method call()');
  }
}

function Bar(){}
Bar.prototype = new Foo();
Bar.prototype.key = 'bar';
Bar.prototype.constructor = Bar;

var Test = new Bar();

console.log(Test.key); //bar
console.log(Bar.prototype.key); //bar
console.log(Foo.prototype.key); //foo
console.log(Test.private_key); //private key
Test.call(); //Call Foo Method call()

當呼叫Test.key時,會叫到Bar.key bar, 另外Test.call()可以叫到Foo.call()

如果做以下修正

var Test = new Bar();
Bar.prototype.key = 'bar2'; //影響Test
Foo.prototype.key = 'foo2'; //無影響Test

console.log(Test.key); //bar2
console.log(Bar.prototype.key); //bar2
console.log(Foo.prototype.key); //foo2

當呼叫Test.key時,會叫到Bar.key bar2

但如果改變Test.key,卻不影響原本的Bar

var Test = new Bar();
Bar.prototype.key = 'bar2'; //影響Test
Foo.prototype.key = 'foo2'; //無影響Test
Test.key = 'test'; 

console.log(Test.key); //test
console.log(Bar.prototype.key); //bar2
console.log(Foo.prototype.key); //foo2

如果沒有在Bar上設定key,擇會往上設定成Foo.key

function Foo(){}
Foo.prototype = {
  'key' : 'foo'
}

function Bar(){}
Bar.prototype = new Foo();

var Test = new Bar();
Foo.prototype.key = 'foo2'; //無影響Test

console.log(Test.key); //foo2
console.log(Bar.prototype.key); //foo2
console.log(Foo.prototype.key); //foo2

[hasOwnProperty]

為了判斷一個物件是否包含 自定義 屬性而 不是 原形上的屬性,我們需要使用繼承 Object.prototypehasOwnProperty 方法。

注意: 判斷一個屬性是否 undefined 是 不夠的。 因為一個屬性可能存在,但是它的值被設成 undefined。 hasOwnProperty 是 JavaScript 中唯一一個處理屬性但是 不 找原型鏈的函式。


[for in 迴圈]

就像其他的 in 操作符一樣, for in 循環也進入所有在物件中的屬性

(這段看不太懂)

results matching ""

    No results matching ""