從JS庫的使用者轉變成JS的開發人員——第一篇 javascript對象

來源:互聯網
上載者:User

此文是《Javascript Elightment》的讀書筆記,希望和有意向從jS庫的使用者轉變成js的開發人員的童鞋們一起分享。

第一篇   javascript 對象建立對象

Js中,所有事物都是對象或者可以表現得像對象。

記住:對象事實上就是一個屬性(名字和對應的值)的容器。

方法其實也是對象的一個屬性,它包含了用來操作對象的function()對象。如果沒有方法,對象除了儲存靜態屬性外什麼也做不了。

建立一個對象:var myObject = new Object();

上面代碼解析: 我們用一個指向Object() 建構函式的Null 物件去建立新對象。

可以把建構函式看成生產預定義好的對象的模板。

我們也可以自己建立一個物件建構函數,用來大量“生產”我們需要的對象。

如:

var Person = function(living, age, gender) {

this.living = living;

this.age = age;

this.gender = gender;

this.getGender = function() {return this.gender;};

};

var cody = new Person(true, 33, 'male');

js 建構函式構建和返回對象執行個體

建構函式的作用是建立一批共用特定屬性和方法的對象。

建構函式在正常時候不外乎是一個函數,但是當被new調用後,這個函數就被特殊對待,因為它要設定正準備建立的對象的屬性值,然後返回一個建好的對象,這個對象就被認作這個建構函式構造出來的執行個體。

Js 原生/內建對象(Native/Built-In Object)的建構函式

Js的9個原生對象:

• Number()

• String()

• Boolean()

• Object()

• Array()

• Function()

• Date()

• RegExp()

• Error()

自訂建構函式

自訂的建構函式名字的首字母最好大寫。

在建立對象的時候可以省去new關鍵字,但是在定義建構函式的時候必須明確地返回一個對象。

如:

var myFunction = function(){return {prop: val}};

上面的做法避免了prototype的繼承。

 

用new執行個體化建構函式

new操作就是告訴js解譯器——我們要建一個相應的建構函式的執行個體。

Math()

Math與其它內建建構函式不一樣,它是一個靜態對象,並不是建構函式,所以不能用new來構建一個執行個體,但是你可以用它已經建好的執行個體(如 Math.PI)。事實上Math只是js用來儲存math方法的一個對象。

注意: Math 是一個靜態對象(一個包含其它方法的容器),不可以用new操作。

 

用建構函式建立速記/字面值(Shorthand/Literal Values)

Js提供了“字面值”的捷徑去製造大多數的內建對象值,所以我們不需要每次都用new操作。

大多數情況字面值方式和new操作做的事是一樣的,除了Number(),String()和Boolean().

如:

var myObject = new Object();
var myObjectLiteral = {};

var myNumber = new Number(23);

var myNumberLiteral = 23;

注意: 用字面值建立string, number, boolean對象,剛開始並不是建立一個真正的複雜的對象,而是單純的一個未經處理資料類型,只有當這個對象被當做對象用(調用建構函式內的方法,擷取屬性)時,js才會為這個字面值建立一個封裝對象,允許這個字面值像對象一樣操作,當建構函式內的方法調用完後,js就會拋棄這個對象,字面值又恢複成單純的資料類型。(這裡解釋了為什麼“js裡所有的事物都是對象或可以像對象一樣操作”)。

原始值(Primitive Values) null,undefined,“string”,10,true,false都不是對象

原始值不是對象,它們只是用來表示簡單的值。

原始值如何在js中儲存和複製

原始值的儲存和操作僅限於數值表面的,不可還原的。

var myString = 'foo' // create a primitive string object

var myStringCopy = myString; // copy its value into a new variable

var myString = null; // manipulate the value stored in the myString variable

/* The original value from myString was copied to myStringCopy. This is confirmed

by updating the value of myString then checking the value of myStringCopy */

console.log(myString, myStringCopy); // logs 'null foo'

原始值的對比

如果不是通過new建立的對象,那麼原始值的類型還是原始類型。如果用new建立對象,即使數值相同,但是類型已經不再是原始類型了,而變成了對象。

var price1 = 10;
var price2 = 10;
var price3 = new Number('10'); // a complex numeric object because new was used
var price4 = price3;
console.log(price1 === price2); // logs true
/* logs false because price3 contains a complex number object and price 1 is
a primitive value */
console.log(price1 === price3);
// logs true because complex values are equal by reference, not value
console.log(price4 === price3);
// what if we update the price4 variable to contain a primitive value?
price4 = 10;
console.log(price4 === price3); /* logs false: price4 is now primitive
rather than complex */

複合值(Complex Values)

內建對象 Object(),Array(),Function(),Date(),Error(),RegExp()都是複合值,因為它們包含一個或多個原始值和複合值。

複合值在js中如何儲存和複製

新建立一個對象後,這個對象會被儲存在記憶體的某個地址裡;當你調用這個對象時,你用對象的名字去獲得記憶體位址裡的值。

對象的複製並不是像原始值一樣單純在數值表面的複製,複製的是對象的引用值/地址值,並不是真的數值,這意味著對象並不是完全被複製。所以,複製的對象和來源物件其實指向同一個地址值,即它們操作的是同一個對象。

var myObject = {};

var copyOfMyObject = myObject; /* not copied by value,

just the reference is copied */

myObject.foo = 'bar'; // manipulate the value stored in myObject

/* Now if we log myObject and copyOfMyObject, they will have a foo property

because they reference the same object. */

console.log(myObject, copyOfMyObject); /* logs 'Object { foo="bar"}Object { foo="bar"}' */

 

注意: String(),Number(),Boolean()被new建立或偷偷被臨時轉成對象,這些值任然是以單純的數值表面儲存和複製。所以即使原始值可以做類似對象一樣的操作,它們的儲存複製方式也不會和對象一樣。

如果想完全複製一個對象,那就必須把來源物件裡的值擷取出來並注入新的對象中。

複合值的對比

只有當兩個對象指向的是同一個對象,即有相同的儲存地址時,兩個對象才是相等的。否則,即使兩個對象看上去完全一樣,它們也是不等的。

var objectFoo = {same: 'same'};

var objectBar = {same: 'same'};

/* logs false, JS does not care that they are identical

and of the same object type */

console.log(objectFoo === objectBar);

// how complex objects are measured for equality

var objectA = {foo: 'bar'};

var objectB = objectA;

console.log(objectA === objectB); /* logs true because they reference

the same object */

綜合物件的動態屬性

已經知道,一個變數指向一個現有的對象時並不是複製這個對象,僅僅是複製了對象的地址。所以一個對象可以擁有很多個引用對象,它們都指向同一個地址的來源物件。

所以,只要這些對象中任意一個的屬性改動,則其它的對象都會一起改動。

原始值和複合值的typeof 操作

值的類型要根據環境來確定。如下面,除了用new操作建立的對象外,其它快捷建立出來的值都是原始類型。

var myNull = null;

var myUndefined = undefined;

var primitiveString1 = "string";

var primitiveString2 = String('string');

console.log(typeof myNull); // logs object? WHAT? Be aware...

console.log(typeof myUndefined); // logs undefined

console.log(typeof primitiveString1, typeof primitiveString2);// logs string string

// Complex Values

var myNumber = new Number(23);

var myString = new String('male');

var myBoolean = new Boolean(false);

console.log(typeof myNumber); // logs object

console.log(typeof myString); // logs object

console.log(typeof myBoolean); // logs object

對象的可變性

因為對象擁有動態屬性的特點,導致了它是可變的,即使是js的內建對象。這意味著你可以隨時隨地改變js中的大多數對象,改變它原配置的屬性,添加屬性方法等(實際上這種做法是不推薦的)。

所有的建構函式執行個體都有指向它們的建構函式的建構函式屬性

每個執行個體都有一個建構函式屬性,這個屬性指向了構造這個執行個體的建構函式。

即使是原始值,也同樣擁有建構函式屬性,但是構造出來的並不是對象,仍是一個原始值。

var myNumber = new Number('23');

var myNumberL = 23; // literal shorthand

var myString = new String('male');

var myStringL = 'male'; // literal shorthand

console.log( // all of these return true

myNumber.constructor === Number,

myNumberL.constructor === Number,

myString.constructor === String,

myStringL.constructor === String);

如果希望自訂的對象的建構函式有確切的名字,則在定義的時候要先給它命名。如

var Person = function Person(){};

每個對象都是特定的建構函式的執行個體

instranceof() 函數可以用來判斷一個對象是否是某個建構函式的執行個體。

註:1. 每個對象都是Object()建構函式的執行個體。

      2. 如果原始值不是new出來的,則在判斷建構函式執行個體時一定會返回false. (e.g., 'foo' instanceof

String // returns false).

建構函式構造的執行個體可以擁有它們獨立的屬性

Js中,對象隨時可以被擴充。但是原始值不可以進行擴充。

var myString = new String();

var myNumber = new Number();

myString.prop = 'test';

myNumber.prop = 'test';

console.log(myString.prop,myNumber.prop); // logs 'test', 'test'

 

// be aware: instance properties do not work with primitive/literal values

var myString = 'string';

var myNumber = 1;

myString.prop = true;

myNumber.prop = true;

// logs undefined, undefined

console.log(myString.prop, myNumber.prop);

註: 除了建構函式的屬性外,執行個體還會從prototype 鏈繼承屬性。如上所述,執行個體也可擁有自己擴充的屬性。

“Javascript Objects” 和 “Object() Objects” 語義上的區別

Javascript Objects 泛指js中的所有對象,Object() Objects特指由Object建構函式構造出來的名字為Objects的對象。

 

後面會繼續更新”第二篇 使用對象和屬性“。

此文為原創,轉載請附連結,謝謝。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.