成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

JavaScript 中的面向?qū)ο?/h1>

開發(fā) 前端
JavaScript 語言本身的設(shè)計(jì)缺陷,誤打誤撞,成了解釋最為徹底的“世界原本的樣子”的計(jì)算機(jī)編程語言;

[[430327]]

本文轉(zhuǎn)載自微信公眾號(hào)「勾勾的前端世界」,作者西嶺。轉(zhuǎn)載本文請聯(lián)系勾勾的前端世界公眾號(hào)。

回憶一下什么是對象:Coding 第一奧義:面向?qū)ο缶幊?/a>

JavaScript 語言本身的設(shè)計(jì)缺陷,誤打誤撞,成了解釋最為徹底的“世界原本的樣子”的計(jì)算機(jī)編程語言;

——西嶺《凡人凡語》

Everything is object (萬物皆對象),JS 語言中將一切都視為 對象 。

JavaScript 語言的對象體系,不基于“類” 創(chuàng)建對象,是基于構(gòu)造函數(shù)(constructor)和原型鏈(prototype)。

簡單方式創(chuàng)建對象

我們可以直接通過 new Object() 創(chuàng)建:

  1. var person = new Object() 
  2. person.name = 'Jack' 
  3. person.age = 18 
  4.  
  5. person.sayName = function () { 
  6.     console.log(this.name

字面量方式創(chuàng)建對象

每次創(chuàng)建通過 new Object() 比較麻煩,所以可以通過它的簡寫形式對象字面量來創(chuàng)建:

  1. var person = { 
  2.   name'Jack'
  3.   age: 18, 
  4.   sayName: function () { 
  5.     console.log(this.name
  6.   } 

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

JavaScript 語言使用構(gòu)造函數(shù)作為對象的模板。

所謂 "構(gòu)造函數(shù)",就是一個(gè)普通的函數(shù),只不過我們專門用它來生成對象,這樣使用的函數(shù),就是構(gòu)造函數(shù)。

它提供模板,描述對象的基本結(jié)構(gòu)。一個(gè)構(gòu)造函數(shù),可以生成多個(gè)對象,這些對象都有相同的結(jié)構(gòu)。

  1. function Person (name, age) { 
  2.   this.name = name 
  3.   this.age = age 
  4.   this.sayName = function () { 
  5.     console.log(this.name
  6.   } 
  7.  
  8. var p1 = new Person('Jack', 18) 
  9. p1.sayName() // => Jack 
  10.  
  11. var p2 = new Person('Mike', 23) 
  12. p2.sayName() // => Mike 

解析構(gòu)造函數(shù)代碼的執(zhí)行

在上面的示例中,使用 new 操作符創(chuàng)建 Person 實(shí)例對象;

以這種方式調(diào)用構(gòu)造函數(shù)會(huì)經(jīng)歷以下 5 個(gè)步驟:

  • 創(chuàng)建一個(gè)空對象,作為將要返回的對象實(shí)例。
  • 將這個(gè)空對象的原型,指向構(gòu)造函數(shù)的prototype屬性。先記住,后面講
  • 將這個(gè)空對象賦值給函數(shù)內(nèi)部的this關(guān)鍵字。
  • 執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼。
  • 返回新對象 (this)
  1. function Person (name, age) { 
  2.   // 當(dāng)使用 new 操作符調(diào)用 Person() 的時(shí)候,實(shí)際上這里會(huì)先創(chuàng)建一個(gè)對象 
  3.   // 然后讓內(nèi)部的 this 指向新創(chuàng)建的對象 
  4.   // 接下來所有針對 this 的操作實(shí)際上操作的就是剛創(chuàng)建的這個(gè)對象 
  5.  
  6.   this.name = name 
  7.   this.age = age 
  8.   this.sayName = function () { 
  9.     console.log(this.name
  10.   } 
  11.  
  12.   // 在函數(shù)的結(jié)尾處會(huì)將 this 返回,也就是這個(gè)新對象 

構(gòu)造函數(shù)和實(shí)例對象的關(guān)系

構(gòu)造函數(shù)是根據(jù)具體的事物抽象出來的抽象模板,實(shí)例對象是根據(jù)抽象的構(gòu)造函數(shù)模板得到的具體實(shí)例對象。

實(shí)例對象由構(gòu)造函數(shù)而來,一個(gè)構(gòu)造函數(shù)可以生成很多具體的實(shí)例對象,而每個(gè)實(shí)例對象都是獨(dú)一無二的。

每個(gè)對象都有一個(gè) constructor 屬性,該屬性指向創(chuàng)建該實(shí)例的構(gòu)造函數(shù)。

反推出來,每一個(gè)對象都有其構(gòu)造函數(shù)

  1. console.log(p1.constructor === Person) // => true 
  2. console.log(p2.constructor === Person) // => true 
  3. console.log(p1.constructor === p2.constructor) // => true 

因此,我們可以通過實(shí)例對象的 constructor 屬性判斷實(shí)例和構(gòu)造函數(shù)之間的關(guān)系。

構(gòu)造函數(shù)存在的問題

以構(gòu)造函數(shù)為模板,創(chuàng)建對象,對象的屬性和方法都可以在構(gòu)造函數(shù)內(nèi)部定義。

  1. function Cat(name, color) { 
  2.   this.name = name
  3.   this.color = color; 
  4.   this.say = function () { 
  5.     console.log('hello'+this.name,this.color); 
  6.   }; 
  7. var cat1 = new Cat('貓''白色');  
  8. var cat2 = new Cat('貓''黑色');  
  9. cat1.say(); 
  10. cat2.say(); 

在該示例中,從表面上看好像沒什么問題,但是實(shí)際上這樣做,有一個(gè)很大的弊端。那就是對于每一個(gè)實(shí)例對象, name 和 say 都是一模一樣的內(nèi)容,每一次生成一個(gè)實(shí)例,都必須為重復(fù)的內(nèi)容,多占用一些內(nèi)存,如果實(shí)例對象很多,會(huì)造成極大的內(nèi)存浪費(fèi)。

那么,能不能將相同的內(nèi)容,放到公共部分,節(jié)約計(jì)算機(jī)資源呢?

原型

JavaScript 的每個(gè)對象都會(huì)繼承一個(gè)父級(jí)對象,父級(jí)對象稱為 原型 (prototype) 對象。

原型也是一個(gè)對象,原型對象上的所有屬性和方法,都能被子對象 (派生對象) 共享,通過構(gòu)造函數(shù)生成實(shí)例對象時(shí),會(huì)自動(dòng)為實(shí)例對象分配原型對象。而每一個(gè)構(gòu)造函數(shù)都有一個(gè)prototype屬性,這個(gè)屬性就是實(shí)例對象的原型對象。

null 沒有自己的原型對象。

這也就意味著,我們可以把所有對象實(shí)例需要共享的屬性和方法直接定義在構(gòu)造函數(shù)的 prototype 屬性上,也就是實(shí)例對象的原型對象上。

  1. function Cat(color) { 
  2.   this.color = color; 
  3.  
  4. Cat.prototype.name = "貓"
  5. Cat.prototype.sayhello = function(){ 
  6.     console.log('hello'+this.name,this.color); 
  7. Cat.prototype.saycolor = function (){ 
  8.     console.log('hello'+this.color); 
  9.  
  10. var cat1 = new Cat('白色');  
  11. var cat2 = new Cat('黑色');  
  12. cat1.sayhello(); 
  13. cat2.saycolor(); 

這時(shí)所有實(shí)例對象的 name 屬性和 sayhello() 、saycolor 方法,其實(shí)都是在同一個(gè)內(nèi)存地址的對象中,也就是構(gòu)造函數(shù)的 prototype 屬性上,因此就提高了運(yùn)行效率節(jié)省了內(nèi)存空間。

原型及原型鏈

構(gòu)造函數(shù)的 prototyp 屬性,就是由這個(gè)構(gòu)造函數(shù) new 出來的所有實(shí)例對象的 原型對象

所有對象都有原型對象。

  1. function Cat(name, color) { 
  2.     this.name = name
  3.  } 
  4.  
  5. var cat1 = new Cat('貓'); 
  6.  
  7. console.log(cat1.__proto__.__proto__.__proto__); 

而原型對象中的屬性和方法,都可以被實(shí)例對象直接使用。

每當(dāng)代碼讀取某個(gè)對象的某個(gè)屬性時(shí),都會(huì)執(zhí)行一次搜索,目標(biāo)是具有給定名字的屬性。

  • 搜索首先從對象實(shí)例本身開始
  • 如果在實(shí)例中找到了具有給定名字的屬性,則返回該屬性的值
  • 如果沒有找到,則繼續(xù)搜索指針指向的原型對象,在原型對象中查找具有給定名字的屬性
  • 如果在原型對象中找到了這個(gè)屬性,則返回該屬性的值
  • 如果還是找不到,就到原型的原型去找,依次類推。
  • 如果直到最頂層的Object.prototype還是找不到,則返回undefined。

而這正是多個(gè)對象實(shí)例共享原型所保存的屬性和方法的基本原理。

對象的屬性和方法,有可能是定義在自身內(nèi),也有可能是定義在它的原型對象上。由于原型本身也是對象,又有自己的原型,所以形成了一條可向上追溯的鏈條,叫 原型鏈(prototype chain)。

注意,不在要原型上形成多層鏈?zhǔn)讲檎遥浅@速M(fèi)資源。

內(nèi)置標(biāo)準(zhǔn)庫與包裝對象

在內(nèi)置標(biāo)準(zhǔn)對象中,對象是 JavaScript 語言最主要的數(shù)據(jù)類型,三種原始類型的值——數(shù)值、字符串、布爾值——在一定條件下,也會(huì)自動(dòng)轉(zhuǎn)為對象,也就是原始類型的“包裝對象”(wrapper)。

所謂“包裝對象”,就是分別與數(shù)值、字符串、布爾值相對應(yīng)的Number、String、Boolean三個(gè)原生對象。這三個(gè)原生對象可以把原始類型的值變成(包裝成)對象。

  1. var v1 = new Number(123); 
  2. var v2 = new String('abc'); 
  3. var v3 = new Boolean(true); 
  4.  
  5. typeof v1 // "object" 
  6. typeof v2 // "object" 
  7. typeof v3 // "object" 
  8.  
  9. v1 === 123 // false 
  10. v2 === 'abc' // false 
  11. v3 === true // false 

包裝對象的最大目的,首先是使得 JavaScript 的對象涵蓋所有的值,其次使得原始類型的值可以方便地調(diào)用某些方法。

原始類型的值,可以自動(dòng)當(dāng)作對象調(diào)用,即調(diào)用各種對象的方法和參數(shù)。

這時(shí),JavaScript 引擎會(huì)自動(dòng)將原始類型的值轉(zhuǎn)為包裝對象實(shí)例,在使用后立刻銷毀實(shí)例。

比如,字符串可以調(diào)用length屬性,返回字符串的長度。

  1. 'abc'.length // 3 

上面代碼中,abc是一個(gè)字符串,本身不是對象,不能調(diào)用length屬性。JavaScript 引擎自動(dòng)將其轉(zhuǎn)為包裝對象,在這個(gè)對象上調(diào)用length屬性。調(diào)用結(jié)束后,這個(gè)臨時(shí)對象就會(huì)被銷毀。這就叫原始類型與實(shí)例對象的自動(dòng)轉(zhuǎn)換。

 

責(zé)任編輯:武曉燕 來源: 勾勾的前端世界
相關(guān)推薦

2009-06-10 22:06:29

JavaScript面向?qū)ο?/a>

2012-01-17 09:34:52

JavaScript

2017-04-21 09:07:39

JavaScript對象編程

2018-12-19 19:30:46

JavaScript創(chuàng)建對象前端

2012-02-27 09:30:22

JavaScript

2012-12-25 10:51:39

IBMdW

2011-05-13 11:05:52

javascript

2011-05-25 10:21:44

Javascript

2011-05-13 09:58:46

javascript

2011-05-13 10:51:25

javascript

2011-05-13 11:17:18

javascript

2011-05-13 11:27:59

javascript

2011-05-13 12:38:58

javascript

2011-05-25 10:59:26

Javascript繼承

2011-05-25 11:15:02

Javascript繼承

2012-03-13 16:39:52

Java

2009-07-14 16:51:50

Jython中的對象

2010-10-08 09:13:15

oop模式JavaScript

2011-06-28 14:11:33

JavaScript

2022-08-15 15:39:23

JavaScript面向?qū)ο?/a>數(shù)據(jù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 九九久久精品 | 欧美aaa级| 欧美日韩久 | 亚洲精品第一页 | 91精品国产91久久综合桃花 | 国产高清免费 | 国产在线1 | 亚州一区二区三区 | 午夜精品一区二区三区在线观看 | 日韩中文字幕在线视频观看 | 国产高清视频在线 | 亚洲大片一区 | 欧美不卡视频一区发布 | 天天色综| 久久久久久看片 | 精品久久网 | 视频在线亚洲 | 国产色视频网站 | 国产香蕉视频在线播放 | 日韩欧美黄色 | 日韩精品一区二区三区中文在线 | 亚洲国产精品一区二区三区 | 国产午夜精品视频 | 久久久久www| 国产精品99999 | 日本一区二区不卡视频 | 中文一区 | 午夜久久久久久久久久一区二区 | 国产精品久久久久久一区二区三区 | 国产精品亚洲片在线播放 | 久久成人国产精品 | 一区二区视屏 | 精品一级 | 久久av在线播放 | 免费观看成人性生生活片 | 日韩精品无码一区二区三区 | 天天插天天搞 | 欧美极品一区二区 | 欧美日韩在线一区二区三区 | 自拍偷拍一区二区三区 | av综合站|