摘要:面向?qū)ο笳Z言使用構(gòu)造函數(shù)作為對象的模板。報錯關(guān)鍵字命令內(nèi)部實(shí)現(xiàn)接受個數(shù)不確定參數(shù),第一個參數(shù)構(gòu)造函數(shù)第二個到第個參數(shù)構(gòu)造函數(shù)傳遞的參數(shù)。等價于獲取構(gòu)造函數(shù)返回數(shù)組第一個元素使用構(gòu)造函數(shù)原型創(chuàng)建一個對象。
JavaScript面向?qū)ο?/strong>
JavaScript 語言使用構(gòu)造函數(shù)(constructor)作為對象的模板。所謂”構(gòu)造函數(shù)”,就是專門用來生成實(shí)例對象的函數(shù)。它就是對象的模板,描述實(shí)例對象的基本結(jié)構(gòu)。一個構(gòu)造函數(shù),可以生成多個實(shí)例對象,這些實(shí)例對象都有相同的結(jié)構(gòu)
構(gòu)造函數(shù)的首字母大寫,區(qū)分一般函數(shù)。
函數(shù)體內(nèi)部使用了this關(guān)鍵字,代表了所要生成的對象實(shí)例。
生成對象的時候,必須使用new命令。
構(gòu)造函數(shù)內(nèi)部使用嚴(yán)格模式 "use strict",防止當(dāng)做一般函數(shù)調(diào)用,這樣就會報錯。
function Person(name, age, sex) { "use strict"; this.name = name; this.age = age; this.sex = sex; } Person() 報錯 new Person("zhangxc", 29, "male");
1、new關(guān)鍵字 命令內(nèi)部實(shí)現(xiàn)
function _new(constructor, params) { // 接受個數(shù)不確定參數(shù),第一個參數(shù):構(gòu)造函數(shù);第二個到第n個參數(shù):構(gòu)造函數(shù)傳遞的參數(shù)。 // 1. 首先將參數(shù)組成一個數(shù)組 // 首先 .slice 這個方法在不接受任何參數(shù)的時候會返回 this 本身,這是一個 Array.prototype 下的方法,因此 this 就是指向調(diào)用 .slice 方法的數(shù)組本身。 var args = Array.prototype.slice.call(arguments); // arguments偽數(shù)組,獲取函數(shù)的所有參數(shù)的偽數(shù)組。 // 等價于 // [].slice.call(arguments); // 2. 獲取構(gòu)造函數(shù) var constructor = args.shift(); // shift()返回數(shù)組第一個元素 // 3. 使用構(gòu)造函數(shù)原型創(chuàng)建一個對象。我們希望以這個現(xiàn)有的對象作為模板,生成新的實(shí)例對象,這時就可以使用Object.create()方法。 var context = Object.create(constructor.prototype); // Object.create()參數(shù)是一個對象,新建的對象繼承參數(shù)對象的所有屬性 // 4. 將參數(shù)屬性附加到對象上面 var result = constructor.apply(context, args); // 5. 返回一個對象 return (typeof result === "object" && result != null) ? result : context; } function Person(name, age, sex) { this.name = name; this.age = age; this.sex = sex; } var args1 = _new(Person, "zhangxc", 18, "male"); // {name: "zhangxc", age: 18, sex: "male"} var args2 = new Person("zhangxc", 18, "male"); // {name: "zhangxc", age: 18, sex: "male"}
new.target屬性
如果當(dāng)前函數(shù)是new命令調(diào)用,new.target指向當(dāng)前函數(shù)(構(gòu)造函數(shù)的名稱),否則為undefined。
function Test() { console.log(new.target === Test); } Test() // false new Test() // true
2、this關(guān)鍵字
this總是指向調(diào)用該方法的對象,在最外面調(diào)用就指向window
bind, call, apply都可以改變this的指向
var name = "window"; var obj = { name: "object" } function fun() { console.log(this.name); } 1、直接調(diào)用 fun() // window 因?yàn)榇藭rfun() this指向window對象 2、fun.call(obj); // "object" call改變了this的指向,此時this指向obj對象,this.name 在obj對象里面取值,而不是window對象了。
詳細(xì)講解連接:https://github.com/mqyqingfen...
3、對象的繼承
JavaScript 語言的繼承不通過 class,而是通過“原型對象”(prototype)實(shí)現(xiàn)。
prototype原型對象
每一個函數(shù)都有一個原型對象
每一個實(shí)例對象都有一個 __proto__屬性
JavaScript 繼承機(jī)制的設(shè)計思想就是,原型對象的所有屬性和方法,都能被實(shí)例對象共享。也就是說,如果屬性和方法定義在原型上,那么所有實(shí)例對象就能共享,不僅節(jié)省了內(nèi)存,還體現(xiàn)了實(shí)例對象之間的聯(lián)系。原型對象的作用,就是定義所有實(shí)例對象共享的屬性和方法。這也是它被稱為原型對象的原因,而實(shí)例對象可以視作從原型對象衍生出來的子對象。
// 定義水果構(gòu)造函數(shù) function Fruit(name, color) { this.name = name; this.color = color; } // 實(shí)例化apple對象 var apple = new Fruit("apple", "red"); // 實(shí)例化banana 對象 var banana = new Fruit("banana", "yellow"); // 如果他們有共同的屬性和方法那么就使用 prototype // 修改 Fruit構(gòu)造函數(shù) Fruit.prototype.address = "china"; Fruit.prototype.eat = function() { console.log(this.name + "-----" + this.color); } apple.addess // china banana.address // china apple.eat() // apple ---- red banana.eat() // banana ---- yellow function M1() { this.hello = "hello"; } function M2() { this.world = "world"; } **// 1、繼承M1,M2自己的屬性和方法(hasOwnProperty)** function S() { M1.call(this); M2.call(this); } **// 2、繼承M1原型鏈上的屬性和方法** S.prototype = Object.create(M1.prototype); **// 3、繼承M2原型鏈上的屬性和方法** Object.assign(S.prototype, M2.prototype); // 指定構(gòu)造函數(shù) S.prototype.constructor = S; var s = new S(); s.hello // "hello" s.world // "world"
4、原型鏈
最透徹的原型鏈講解 哈哈
**1. 每一個函數(shù)都有prototype屬性指向他的原型對象** **2. 每一個對象都有__proto__屬性指向他的原型對象**
然后以Date()時間 構(gòu)造函數(shù)為例講解
證明:
var data = new Date(); 因?yàn)椋?data是一個實(shí)例對象所以他有__proto__屬性指向他的原型對象 Date是一個構(gòu)造函數(shù)所以他有prototype屬性指向他的原型對象 所以:Date.prototype == data.__proto__ // Date{} true data.__proto__是一個對象 因?yàn)椋簀avascript規(guī)定所有對象都有原型 所以: data.__proto__.__proto__ == Object.prototype // true 這就是原型鏈了 data.__proto__.__proto__ data對象繼承了 Date Object 原型對象的屬性和方法。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/101634.html
摘要:是完全的面向?qū)ο笳Z言,它們通過類的形式組織函數(shù)和變量,使之不能脫離對象存在。而在基于原型的面向?qū)ο蠓绞街?,對象則是依靠構(gòu)造器利用原型構(gòu)造出來的。 JavaScript 函數(shù)式腳本語言特性以及其看似隨意的編寫風(fēng)格,導(dǎo)致長期以來人們對這一門語言的誤解,即認(rèn)為 JavaScript 不是一門面向?qū)ο蟮恼Z言,或者只是部分具備一些面向?qū)ο蟮奶卣鳌1疚膶⒒貧w面向?qū)ο蟊疽?,從對語言感悟的角度闡述為什...
摘要:由構(gòu)造函數(shù)返回的對象就是表達(dá)式的結(jié)果。如果構(gòu)造函數(shù)沒有顯式返回一個對象,則使用步驟創(chuàng)建的對象。運(yùn)算符返回一個布爾值,表示對象是否為某個構(gòu)造函數(shù)的實(shí)例。 面向?qū)ο?本人能力有限,有誤請斧正 本文旨在復(fù)習(xí)面向?qū)ο?不包含es6) 本文學(xué)習(xí)思維 創(chuàng)建對象的方式,獲取對象屬性 構(gòu)造函數(shù),構(gòu)造函數(shù)的new 做了什么 原型與原型對象 原型鏈 繼承(借用構(gòu)造繼承、原型繼承、組合繼承、寄生組合繼承)...
摘要:如果要理解基于原型實(shí)現(xiàn)面向?qū)ο蟮乃枷?,那么理解中得三個重要概念構(gòu)造函數(shù)原型原型鏈對幫助理解基于原型的面向?qū)ο笏枷刖惋@得尤為重要。函數(shù)對象的原型在中,函數(shù)是一種特殊的對象,所有的函數(shù)都是構(gòu)造函數(shù)的實(shí)例。 介紹 和java這種基于類(class-base)的面向?qū)ο蟮木幊陶Z言不同,javascript沒有類這樣的概念,但是javascript也是面向?qū)ο蟮恼Z言,這種面向?qū)ο蟮姆绞匠蔀?基...
摘要:情況沒有明確作用對象的情況下,通常為全局對象例如函數(shù)的回調(diào)函數(shù),它的就是全局對象。正因如此,機(jī)器可以作為這類對象的標(biāo)志,即面向?qū)ο笳Z言中類的概念。所以機(jī)器又被稱為構(gòu)造函數(shù)。原型鏈也就是繼承鏈。 JS面向?qū)ο蠖?this/原型鏈/new原理 阮一峰JavaScript教程:面向?qū)ο缶幊?阮一峰JavaScript教程:實(shí)例對象與 new 命令 阮一峰JavaScript教程:this 關(guān)...
摘要:對象重新認(rèn)識面向?qū)ο竺嫦驅(qū)ο髲脑O(shè)計模式上看,對象是計算機(jī)抽象現(xiàn)實(shí)世界的一種方式。除了字面式聲明方式之外,允許通過構(gòu)造器創(chuàng)建對象。每個構(gòu)造器實(shí)際上是一個函數(shù)對象該函數(shù)對象含有一個屬性用于實(shí)現(xiàn)基于原型的繼承和共享屬性。 title: JS對象(1)重新認(rèn)識面向?qū)ο? date: 2016-10-05 tags: JavaScript 0x00 面向?qū)ο?從設(shè)計模式上看,對象是...
閱讀 3711·2021-09-22 15:34
閱讀 1222·2019-08-29 17:25
閱讀 3427·2019-08-29 11:18
閱讀 1399·2019-08-26 17:15
閱讀 1770·2019-08-23 17:19
閱讀 1259·2019-08-23 16:15
閱讀 743·2019-08-23 16:02
閱讀 1364·2019-08-23 15:19