JavaScript高级程序设计 扩展--关于动态原型_javascript技巧
但是作者Nicholas C. Zakas在【动态原型】方式创建对象的时候没有深究可能会存在的问题和解决方案。而仅仅在继承的时候对【动态原型】的瓶颈作了说明。即在作子类继承的时候,不能通过动态原型的方式来实现。
原文大致如下:
继承机制不能采用动态化的原因是:prototype对象的唯一性。实例代码:
function A (i) {
this.a = i;
if (typeof A._init == 'undefined') {
A.prototype.func = function () {
return 0;
}
A._init = 1;
}
}
function subA (j) {
A.call(this, 1);
this.j = j;
if (typeof subA._init == 'undefined') {
subA.prototype = new A();
subA.prototype.func_sub = function () {
return ++j;
}
subA._init = 1;
}
}
var sub_a = new subA(1);
alert(sub_a.func_sub()); //error: sub_a.func_sub is not a function
Nicholas解释说在代码运行前,对象已被实例,并与prototype联系,在当前对prototype对象替换不会对它产生任何影响,即当前的替换是访问不到的,只有未来对象的实例才会反映出这种改变。于是第一个实例对象就会不正确。但第二个及以后的子类实例都没问题。
解决方法就是在构造函数外赋予新的prototype对象:
function A (i) {
this.a = i;
if (typeof A._init == 'undefined') {
A.prototype.func = function () {
return 0;
}
A._init = 1;
}
}
function subA (j) {
A.call(this, 1);
this.j = j;
if (typeof subA._init == 'undefined') {
subA.prototype.func_sub = function () {
return ++j;
}
subA._init = 1;
}
}
subA.prototype = new A();
var sub_a = new subA(1);
alert(sub_a.func_sub()); //2
可惜这违反了我们为什么使用动态原型的初衷。
使用动态原型的初衷本来就是要让构造函数能“统一江山”,在视觉上让人觉得原型方法是类构造的一部分。
以上是《JavaScript高级程序设计》中对动态原型继承小节的大概内容。
可是Nicholas在先前的章节讲对象构造的【动态原型】方式中,似乎忘了提这个同样的问题。我们看看上文中最后一个例子:
var Obj = function (name) {
this.name = name;
this.flag = new Array('A', 'B');
if (typeof Obj._init == 'undefined') {
Obj.prototype = {
showName : function () {
alert(this.name);
}
};
Obj._init = true;
}
}
var obj1 = new Obj('aa');
var obj2 = new Obj('bb');
obj1.showName(); //error: is not a function
obj2.showName(); // bb;
是的,这个问题其实和子类继承中出现的问题如出一辙,prototype在当前的替换是不会对该对象有任何影响的,只有在未来的实例中可见。如果按照Nicholas处理动态原型继承的方式中说的一样,那就意味着只能在构造函数外边重新赋予prototype对象。那么这不就成了【构造函数/原型混合】方式了吗?所谓的【动态原型】方式也就不存在了...
其实我们可以想想,为什么在【构造函数/原型混合】这种已经基本没有副作用的构建对象方式后面还要在写一节【动态原型】方式。作者的意图无非就是想让构造函数在视觉上更为统一么。其实仅仅要视觉上的统一可以不用动态原型的。
var Obj = function () {
function __initialize (name) {
this.name = name;
this.flag = new Array('A', 'B');
}
__initialize.prototype = {
showName : function () {
alert(this.name);
},
showFlag : function () {
alert(this.flag);
}
}
return __initialize;
}();
var obj1 = new Obj('aa');
var obj2 = new Obj('bb');
obj1.showName(); // aa
obj2.showName(); // bb
其实上面的方式就可以算是视觉的统一了,Obj的构造函数内通过__initialize来初始化属性,通过__initialize.prototype原型初始化方法。只不过稍微有点“小作弊”的感觉,__initialize代理了Obj的初始化...
下面是来自tangoboy的“构造类”的封装,其实思路和上面基本一致,唯一不同的是他把属性也用原型方式创建了,同时把初始化属性和方法都扔到了构造函数参数对象里。方便自定义:
/* == form tangoboy == */
window['$Class'] = {
//创建一个类 混合构造函数/原型方式
create: function(config) {
var obj = function(){},config = config||{};
//过滤构造方法和原型方法
obj = obj.prototype.constructor = config["__"]||obj;
delete config["__"];
obj.prototype = config;
return obj;
}
}
/* -- eg -- */
var man = $Class.create({
__ : function (name) {
this.name = name;
},
sex : 'male',
showName : function () {
alert(this.name);
}
});
var me = new man('ru');
me.showName(); //ru
其实如果硬要追求视觉的统一也可以不用动态原型的方式。说到底看看上面的思路,已经回溯到了我们最常用的“类构造”方式:
var Class = {
create : function () {
return function () {
this.initialize.apply(this, arguments);
}
}
}
相信上面这段代码大家或许都不会陌生,如果细究下去,会发现其实和上面的代码都一致,用initialize函数作了初始化的代理,从而完成了视觉的统一。

熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

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

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