一、建立物件的幾種方式
1、各自獨立宣告模式
var box1 = new Object(); //声明第一个对象并给各属性赋值 box1.name = 'Lee'; box1.age = 100; box1.run = function () { return this.name + this.age + '运行中...'; }; alert(box.run()); var box2 = new Object(); //声明第二个对象并给属性赋值 box2.name = 'Jack'; box2.age = 200; box2.run = function () { return this.name + this.age + '运行中...'; }; alert(box2.run());
此時box2和box1是互相獨立的,不會混淆。
但是這樣子每聲明一個結構相同的對象,都得加一段程式碼,特別不方便,所以有了下面的工廠模式。
2、工廠模式
function createObject(name, age) { //集中实例化的函数 var obj = new Object(); obj.name = name; obj.age = age; obj.run = function () { return this.name + this.age + '运行中...'; }; return obj; }
這樣子每次new物件時只需呼叫createObject()方法即可,同時,也可以傳參初始化物件。
但由於new出來的物件都從屬於Object,當我要讓new出來的物件在本質做一些區分的時候,就不行了,此時就有了更簡便的建構子模式。
3、建構函式模式
function Box(name, age) { this.name = name; this.age = age; this.run = function () { return this.name + this.age + '运行中...'; }; } var box1 = new Box('Lee', 100); var box2 = new Box('Jack', 200); alert(box1.run()); alert(box1 instanceof Box); //很清晰的识别他从属于Box
建構子模式很大程度上解決了物件重複使用及傳參初始化問題,是最常用的new物件的模式。
注意:
此處box1.run != box2.run, 因為他們判斷的是引用位址,由此可知,兩個物件的方法分別儲存在不同的地方,是兩個不同的方法。
但 box1.run() == box2.run(),因為它們傳回值一樣。
當有了物件以後,自然而然就會涉及到物件屬性及方法的共享問題(例如,在java中子類別們共享父類別的成員變數及方法)。
建構函式模式建立出來的物件說白了還是互相獨立的(例如上面的box1.run != box2.run),如果我要在兩個物件之間共用某些屬性的話,就必須採用原型prototype了。
二、透過原型建立物件
1、原型模式
function Box() {} //声明一个构造函数 Box.prototype.name = 'Lee'; //在原型里添加属性 Box.prototype.age = 100; Box.prototype.arr = ['aaa','bbb']; Box.prototype.run = function () { //在原型里添加方法 return this.name + this.age + '运行中...'; }; var box1 = new Box(); var box2 = new Box(); //修改普通属性,看下会不会影响prototype alert(box1.name); //Lee box1.name = 'Rinima'; alert(box1.name); //Rinima alert(box2.name); //Lee,修改box1的普通属性,相当于直接在box1中添加一个属性,是不会牵扯到原型中的属性的。 //这一点非常好。但是如果是引用对象(数组)的话,就有问题了。 //修改引用属性,看下会不会影响prototype alert(box1.arr); //aaa,bbb box1.arr.push('ccc'); alert(box1.arr); //aaa,bbb,ccc alert(box2.arr); //aaa,bbb,ccc,修改box1的引用属性,却牵扯到了原型中的属性。 //这是因为arr只是个引用地址,指向数组真实存储的位置,修改box1中的引用属性就是修改引用所指向的数组,所以原型也被修改了 //这是我们不希望看到的!
此模式的優點:
1、所new出來的物件在prototype中的屬性是共享的,此時box1.run == box2.run
2、能保證所new的物件實例的屬性完全統一(和缺點2相對)
該模式的缺點:
1、當含有引用型別的屬性時,引用型別所指向的屬性是存在prototype中,直接在物件中修改引用屬性就把所有物件的引用屬性都修改了
2、該種模式省略了初始化傳參,使得new出來的所有屬性都是一樣的
1.1、原型字面量模式
(原型模式的另一個模式,大體上差別不大,都屬於原型模式)
function Box() {}; Box.prototype = { //使用字面量的方式 constructor : Box, name : 'Lee', age : 100, run : function () { return this.name + this.age + '运行中...'; } };
此模式繼承了原型模式的所有優缺點,但是也有自己特有的優缺點
優點: 更好的體現了封裝性
缺點: constructor沒有指向自身,必須手動強制指向
2、建構子+原型模式
function Desk(name, age) { //不共享的使用构造函数 this.name = name; this.age = age; this.family = ['aaa', 'bbb', 'ccc']; }; Desk.prototype = { //共享的使用原型模式 constructor : Desk, run : function () { return this.name + this.age + this.family; } }; var desk1 = new Desk('Lee',100); var desk2 = new Desk('Jack',200); alert(desk1.family); //aaa,bbb,ccc desk1.family.push('ddd'); alert(desk1.family); //aaa,bbb,ccc,ddd alert(desk2.family); //aaa,bbb,ccc
優點: 這種模式完美解決了共享屬性與不共享屬性的問題,而且可以精確控制,是非常不錯的模式。
缺點: 但是此種辦法,原型與建構子相分離,讓人感覺很怪異,體現不了封裝。
3、動態原型模式
function Box(name ,age) { //将所有信息封装到函数体内 this.name = name; //不共享的属性 this.age = age; if (typeof this.arr != 'object') { //共享的属性 alert('在第一次调用的时候...arr'); Box.prototype.arr = ['aaa','bbb']; } if (typeof this.run != 'function') { alert('在第一次调用的时候...run'); Box.prototype.run = function () { return this.name + this.age + '运行中...'; }; } } var box1 = new Box(); var box2 = new Box(); alert( box1.arr ); //aaa,bbb box1.arr.push('ccc'); alert( box1.arr ); //aaa,bbb,ccc alert( box2.arr ); //aaa,bbb
優點:這個模式繼承了上一個模式(建構+原型)的所有優點,同時也完美解決了封裝性問題
注意:此種模式書寫原型時不可用字面量模式,會切斷實例和新原型之間的聯繫的。 ? ? ?
基本上到這裡,以上兩種模式已經能處理大多數問題,而且是比較好的模式了。
但是,還是有一些比較特定的需求,需要用到以下兩種比較另類的模式。
4、寄生建構子模式(工廠模式+建構子模式)
function Box(name, age) { var obj = new Object(); obj.name = name; obj.age = age; obj.run = function () { return this.name + this.age + '运行中...'; }; return obj; }
5、穩健建構子模式
function Box(name , age) { var obj = new Object(); obj.run = function () { return name + age + '运行中...'; //直接打印参数即可 }; return obj; }
穩做建構函式模式,是當建構函式裡不允許使用this,外部實例化時不準用new時,才需要用到的模式。
我也不知道為啥會出現這樣那麼奇葩的需求。不過這麼多的創建物件模式,確實比Java眼花撩亂多了。
以上是理解JavaScript創建對象與透過原型創建對象的詳細內容。更多資訊請關注PHP中文網其他相關文章!

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。

C和C 在JavaScript引擎中扮演了至关重要的角色,主要用于实现解释器和JIT编译器。1)C 用于解析JavaScript源码并生成抽象语法树。2)C 负责生成和执行字节码。3)C 实现JIT编译器,在运行时优化和编译热点代码,显著提高JavaScript的执行效率。

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

WebStorm Mac版
好用的JavaScript開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能