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展示后端应用。
