日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Javascript 对象一(对象详解)

發(fā)布時間:2023/12/9 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Javascript 对象一(对象详解) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

JS創(chuàng)建對象的幾種方法

1. Object 構(gòu)造函數(shù) 創(chuàng)建

2. 對象字面量表示法 創(chuàng)建

3. 使用工廠模式創(chuàng)建對象

在 Car 函數(shù)中,返回的是一個對象。那么我們就無法判斷返回的對象究竟是一個什么樣的類型。于是就出現(xiàn)了第四種創(chuàng)建對象的模式

4. 使用構(gòu)造函數(shù)創(chuàng)建對象

構(gòu)造函數(shù)始終要應(yīng)該以一個大寫字母開頭,而非構(gòu)造函數(shù)則應(yīng)該以一個小寫字母開頭。

構(gòu)造函數(shù)與工程模式相比:
沒有顯示地創(chuàng)建對象
直接將屬性和方法賦給了this對象
沒有return語句
終于可以識別的對象的類型,可以使用instanceof操作符來進行自主檢測

構(gòu)造函數(shù)執(zhí)行流程:

構(gòu)造函數(shù)創(chuàng)建對象的缺點:
每個對象里面都有公用的函數(shù),就是每個方法都要在每個實例上重新創(chuàng)建一遍,如果方法的數(shù)量很多,就會占用很多不必要的內(nèi)存。
于是出現(xiàn)了第五種創(chuàng)建對象的方法

5. 原型創(chuàng)建對象模式


6. 組合使用構(gòu)造函數(shù)模式和原型模式
這種模式是ECMAScript中使用最廣泛,認可度最高的一種創(chuàng)建自定義類型的方法,可以說這是用來定義引用類型的一種默認模式

原型、原型鏈


原型prototype:在javascript中,每個函數(shù)都有一個特殊的屬性叫作原型(prototype)。注意函數(shù)對象才有prototype屬性。prototype屬性又指向了一個prototype對象


__proto__屬性:每個對象(除了null)都擁有這樣一個屬性,這個屬性是一個指針,它指向一個名叫做原型對象的內(nèi)存堆。而原型對象也是一個對象,因此又含有自己的[[prototype]]屬性,又指向下一個原型對象,終點指向我們的Object.prototype對象。



constructor 屬性:每個實例對象都從原型中繼承了一個constructor屬性,存在于每一個function的prototype屬性中,這個constructor保存了指向function的一個引用
在 constructor 屬性的末尾添加一對圓括號括號中包含所需的參數(shù))實例對象也可以百年城構(gòu)造器創(chuàng)建另一個對象實例

constructor屬性不影響任何javascript的內(nèi)部屬性。instanceof檢測對象的原型鏈,通常你是無法修改的。
constructor其實沒有什么用,只是javascript語言設(shè)計的歷史遺留物。

原型鏈:
1)原型鏈的最高指向: null
所有函數(shù)的默認原型都是Object的實例,因此默認原型都會包含一個內(nèi)部指針,指向Object.prototype。 Object的指針最后指向null
2)實例和原型的關(guān)系:
當讀取實例的屬性時,如果找不到實例的屬性,就會查找與對象關(guān)聯(lián)的原型的屬性,如果還是查找不到,就查找原型的原型,一直到頂級為止。這樣就構(gòu)成了一個原型鏈
3) 原型的原型:
實例出來的var person = new Person()person通過__proto__指向構(gòu)造函數(shù)的原型Person.prototype,然后構(gòu)造函數(shù)的原型指向Object的原型,即是Person.prototype.__proto__指向Object.prototype。

Object.prototype.__proto__ // null

實例講解:

function Person(name){this.name = name; } Person.prototype.sayName = function(){console.log(this.name); }var person = new Person("Lotus"); person.age = 23; person.sayName(); // Lotus

<html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>canvas</title><style>body{margin: 0;padding: 0;position: relative;}#myCanvas{position: absolute;left: 50%;top: 50%;background: #000;margin-left: -300px;margin-top: -150px;}</style> </head> <body><canvas id="myCanvas" width="600" height="300" style="border: 1px solid #000;"></canvas><script type="text/javascript">window.onload = function(){var c = document.getElementById('myCanvas');var grd = ""; // 漸變的顏色// 上下文var context = c.getContext("2d");if(context){// x,y,r 坐標和半徑function Star(x,y,r){this.x = x;this.y = y;this.r = r;this.init(this.x,this.y,this.r);}// 繪制星星Star.prototype.init = function(x,y,r){context.beginPath();// 漸變顏色grd = context.createRadialGradient(x,y,r-2,x,y,r+2)grd.addColorStop(0, 'white');grd.addColorStop(1, 'yellow');context.fillStyle=grd;// 畫圓context.arc(x,y,r,0,2*Math.PI);// 填充顏色context.fill();context.closePath();}// 創(chuàng)建星星for(var i = 0; i < 200; i++){var x = Math.floor(Math.random()*600);var y = Math.floor(Math.random()*300);var r = Math.floor(Math.random()*3)+2;new Star(x,y,r)}}else{var div = document.createElement("div");div.innerHTML = "您的瀏覽器不支持canvas,請升級瀏覽器!";document.getElementsByTagName("body")[0].appendChild(div);}}</script> </body> </html>

繼承

  • 構(gòu)造函數(shù)、原型和實例之間的關(guān)系:
    每個構(gòu)造函數(shù)都有一個原型對象,原型對象都包含一個指向構(gòu)造函數(shù)的指針,而實例都包含一個原型對象的指針。
  • 繼承的本質(zhì):即重寫原型對象,代之以一個新類型的實例。

1、原型鏈繼承

function SuperType() {this.property = true; }SuperType.prototype.getSuperValue = function() {return this.property; }function SubType() {this.subproperty = false; }// 這里是關(guān)鍵,創(chuàng)建SuperType的實例,并將該實例賦值給SubType.prototype SubType.prototype = new SuperType(); SubType.prototype.getSubValue = function() {return this.subproperty; }var instance = new SubType(); console.log(instance.getSuperValue()); // true


存在的缺點:多個實例對引用類型的操作會被篡改。

2、借用構(gòu)造函數(shù)繼承
使用父類的構(gòu)造函數(shù)來增強子類實例,等同于復(fù)制父類的實例給子類(不使用原型)

function SuperType(){this.color=["red","green","blue"]; } function SubType(){//繼承自SuperTypeSuperType.call(this); } var instance1 = new SubType(); instance1.color.push("black"); alert(instance1.color);//"red,green,blue,black"var instance2 = new SubType(); alert(instance2.color);//"red,green,blue"

缺點:
只能繼承父類的實例屬性和方法,不能繼承原型屬性/方法
無法實現(xiàn)復(fù)用,每個子類都有父類實例函數(shù)的副本,影響性能

3、組合繼承
用原型鏈實現(xiàn)對原型屬性和方法的繼承,用借用構(gòu)造函數(shù)技術(shù)來實現(xiàn)實例屬性的繼承。

function SuperType(name){this.name = name;this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){alert(this.name); };function SubType(name, age){// 繼承屬性// 第二次調(diào)用SuperType()SuperType.call(this, name);this.age = age; }// 繼承方法 // 構(gòu)建原型鏈 // 第一次調(diào)用SuperType() SubType.prototype = new SuperType(); // 重寫SubType.prototype的constructor屬性,指向自己的構(gòu)造函數(shù)SubType SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){alert(this.age); };var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29var instance2 = new SubType("Greg", 27); alert(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge(); //27


缺點:
第一次調(diào)用SuperType():給SubType.prototype寫入兩個屬性name,color。
第二次調(diào)用SuperType():給instance1寫入兩個屬性name,color。
缺點就是在使用子類創(chuàng)建實例對象時,其原型中會存在兩份相同的屬性/方法。

4、原型式繼承
利用一個空對象作為中介,將某個對象直接賦值給空對象構(gòu)造函數(shù)的原型。

function object(obj){function F(){}F.prototype = obj;return new F(); }var person = {name: "Nicholas",friends: ["Shelby", "Court", "Van"] };var anotherPerson = object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob");var yetAnotherPerson = object(person); yetAnotherPerson.name = "Linda"; yetAnotherPerson.friends.push("Barbie");alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"

缺點:
原型鏈繼承多個實例的引用類型屬性指向相同,存在篡改的可能。
無法傳遞參數(shù)
ES5中存在Object.create()的方法,能夠代替上面的object方法

5、寄生式繼承
在原型式繼承的基礎(chǔ)上,增強對象,返回構(gòu)造函數(shù)

function createAnother(original){var clone = object(original); // 通過調(diào)用 object() 函數(shù)創(chuàng)建一個新對象clone.sayHi = function(){ // 以某種方式來增強對象alert("hi");};return clone; // 返回這個對象 }var person = {name: "Nicholas",friends: ["Shelby", "Court", "Van"] }; var anotherPerson = createAnother(person); anotherPerson.sayHi(); //"hi"

缺點:跟4原型式繼承一樣

6、寄生組合式繼承
結(jié)合借用構(gòu)造函數(shù)傳遞參數(shù)和寄生模式實現(xiàn)繼承

function inheritPrototype(subType, superType){var prototype = Object.create(superType.prototype); // 創(chuàng)建對象,創(chuàng)建父類原型的一個副本prototype.constructor = subType; // 增強對象,彌補因重寫原型而失去的默認的constructor 屬性subType.prototype = prototype; // 指定對象,將新創(chuàng)建的對象賦值給子類的原型 }// 父類初始化實例屬性和原型屬性 function SuperType(name){this.name = name;this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){alert(this.name); };// 借用構(gòu)造函數(shù)傳遞增強子類實例屬性(支持傳參和避免篡改) function SubType(name, age){SuperType.call(this, name);this.age = age; }// 將父類原型指向子類 inheritPrototype(SubType, SuperType);// 新增子類原型屬性 SubType.prototype.sayAge = function(){alert(this.age); }var instance1 = new SubType("xyc", 23); var instance2 = new SubType("lxy", 23);instance1.colors.push("2"); // ["red", "blue", "green", "2"] instance1.colors.push("3"); // ["red", "blue", "green", "3"]



7、混入方式繼承多個對象

function MyClass() {SuperClass.call(this);OtherSuperClass.call(this); }// 繼承一個類 MyClass.prototype = Object.create(SuperClass.prototype); // 混合其它 Object.assign(MyClass.prototype, OtherSuperClass.prototype); // 重新指定constructor MyClass.prototype.constructor = MyClass;MyClass.prototype.myMethod = function() {// do something }; Object.assign會把 OtherSuperClass原型上的函數(shù)拷貝到 MyClass原型上,使 MyClass 的所有實例都可用 OtherSuperClass 的方法。

8、ES6類繼承extends
extends關(guān)鍵字主要用于類聲明或者類表達式中,以創(chuàng)建一個類,該類是另一個類的子類。其中constructor表示構(gòu)造函數(shù),一個類中只能有一個構(gòu)造函數(shù),有多個會報出SyntaxError錯誤,如果沒有顯式指定構(gòu)造方法,則會添加默認的 constructor方法,使用例子如下。

class Rectangle {// constructorconstructor(height, width) {this.height = height;this.width = width;}// Getterget area() {return this.calcArea()}// MethodcalcArea() {return this.height * this.width;} }const rectangle = new Rectangle(10, 20); console.log(rectangle.area); // 輸出 200----------------------------------------------------------------- // 繼承 class Square extends Rectangle {constructor(length) {super(length, length);// 如果子類中存在構(gòu)造函數(shù),則需要在使用“this”之前首先調(diào)用 super()。this.name = 'Square';}get area() {return this.height * this.width;} }const square = new Square(10); console.log(square.area); // 輸出 100

extends繼承的核心代碼如下,其實現(xiàn)和上述的寄生組合式繼承方式一樣

function _inherits(subType, superType) {// 創(chuàng)建對象,創(chuàng)建父類原型的一個副本// 增強對象,彌補因重寫原型而失去的默認的constructor 屬性// 指定對象,將新創(chuàng)建的對象賦值給子類的原型subType.prototype = Object.create(superType && superType.prototype, {constructor: {value: subType,enumerable: false,writable: true,configurable: true}});if (superType) {Object.setPrototypeOf ? Object.setPrototypeOf(subType, superType) : subType.__proto__ = superType;} }

查看原文:
https://juejin.im/post/5b150fcf518825139b18de11#heading-0
https://juejin.im/post/5acf22aef265da238c3b0f78#heading-3
https://juejin.im/post/5bcb2e295188255c55472db0

總結(jié)

以上是生活随笔為你收集整理的Javascript 对象一(对象详解)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。