我一直在构建一个小型JS框架供我工作使用,我想使用Douglas Crockford的原型继承模式.我想我对原型对象的工作原理有了一般的了解,但不清楚的是我将使用这种模式的方式超出了最简单的例子.
我会把它充实到我明白的地步.
(function () {
'use strict';
var Vehicles = {};
Vehicles.Vehicle = function () {
this.go = function () {
//go forwards
};
this.stop = function () {
//stop
};
};
Vehicles.Airplane = Object.create(Vehicles.Vehicle());
}());
Run Code Online (Sandbox Code Playgroud)
所以现在我的Vehicles.Airplane对象可以去()和停止(),但我想要更多.我想将takeOff()和land()方法添加到此对象.之后我可以使用丑陋的点符号:
Vehicles.Airplane.takeOff = function () {
//take off stuff
}
Run Code Online (Sandbox Code Playgroud)
但这似乎是错误的,特别是如果我要添加许多方法或属性.这里提出的问题似乎与我的非常相似,但答案对我来说并不完全正确.答案表明我应该在使用Object.create之前构建一个对象文字,并且我应该将该对象文字传递给create方法.但是,在给出的示例代码中,看起来它们的新对象现在根本没有继承.
我希望的是一些语法类似于:
Vehicles.Airplane = Object.create(Vehicles.Vehicle({
this.takeOff = function () {
//takeOff stuff
};
this.land = function () {
//land stuff
};
}));
Run Code Online (Sandbox Code Playgroud)
我知道这个语法现在会用Object.create打破,因为我当然要传递Vehicle.Vehicle一个函数而不是一个对象文字.这不是重点.我想知道我应该以什么方式将一个新属性构建到一个继承自另一个的对象中,而不必在事后用点符号一次列出一个.
编辑:
Bergi在经历了一些关于这个话题的痛苦思考后,我想我真的想要用你所描述的"古典模式".这是我的第一次尝试(现在使用实际的代码片段,而不是模拟假设 - 你甚至可以看到我糟糕的方法存根):
CS.Button = function (o) …Run Code Online (Sandbox Code Playgroud) 在一个项目中,我维护我们广泛使用null原型对象作为穷人的替代(仅限字符串键)映射,这些映射在许多较旧的ES6之前的浏览器中不是本机支持的.
基本上,要动态创建一个null原型对象,可以使用:
var foo = Object.create(null);
Run Code Online (Sandbox Code Playgroud)
这保证了新对象没有继承属性,例如"toString","constructor","__ proto__",这对于这个特定的用例是不可取的.
由于这种模式在代码中多次出现,我们提出了编写构造函数的想法,该构造函数将创建其原型具有null原型且没有自己的属性的对象.
var Empty = function () { };
Empty.prototype = Object.create(null);
Run Code Online (Sandbox Code Playgroud)
然后,要创建一个没有自己或继承属性的对象,可以使用:
var bar = new Empty;
Run Code Online (Sandbox Code Playgroud)
为了提高性能,我编写了一个测试,并发现在Object.create所有浏览器中,本机方法的意外执行速度比涉及带有ad hoc原型的额外构造函数的方法慢得多:http://jsperf.com/blank-object - 创造.
我非常期待后一种方法更慢,因为它涉及调用用户定义的构造函数,这在前一种情况下不会发生.
造成这种性能差异的原因是什么?
我正在看到有关"新"Object.create的帖子,它使枚举可配置.但是,它依赖于Object.defineProperty方法.我找不到这种方法的跨浏览器实现.
我们是不是在为旧的Object.create写作?我不能写出在IE6/7中无效的东西.
new到目前为止,我一直在使用JavaScript中的关键字.我一直在阅读Object.create,我想知道是否应该使用它.我不太明白的是我经常需要运行构造代码,因此我看不到Object.create它将如何工作,因为它不会触发任何运行的函数.
谁能告诉我,在哪种情况下我应该使用Object.create而不是new?
我认为差异已经在我的脑海中点击,但我想确定.
他说,在道格拉斯克罗克福德页面上的JavaScript Prototypal Inheritance中
在原型系统中,对象从对象继承.但是,JavaScript缺少执行该操作的运算符.相反,它有一个新的运算符,这样new f()就会产生一个从f.prototype继承的新对象.
我真的不明白他在那句话中想说的是什么,所以我进行了一些测试.在我看来,关键的区别在于,如果我在纯原型系统中基于另一个对象创建一个对象,那么所有父父成员应该在新对象的原型上,而不是在新对象本身上.
这是测试:
var Person = function(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.toString = function(){return this.name + ', ' + this.age};
// The old way...
var jim = new Person("Jim",13);
for (n in jim) {
if (jim.hasOwnProperty(n)) {
console.log(n);
}
}
// This will output 'name' and 'age'.
// The pure way...
var tim = Object.create(new Person("Tim",14));
for (n in tim) {
if (tim.hasOwnProperty(n)) {
console.log(n);
}
}
// This …Run Code Online (Sandbox Code Playgroud) 在Javascript中,我可以像这样创建一个"类":
var MyClass = function(){
return this;
};
var myClassInstance = new MyClass();
Run Code Online (Sandbox Code Playgroud)
执行上述操作和执行此操作之间有什么区别:
var MyClass = {};
var myClassInstance = Object.create(MyClass);
Run Code Online (Sandbox Code Playgroud)
有没有理由使用一个而不是另一个?
好像我终于理解了JavaScript继承以及如何正确地完成它.这是我的代码:
function Human(eyes) {
this.eyes = eyes ? "Not blind" : "Blind";
}
Human.prototype.canSee = function () {
return this.eyes;
};
function Male(name, eyes) {
Human.call(this, eyes);
this.name = name;
}
Male.prototype = Object.create(Human.prototype);
var Sethen = new Male("Sethen", true);
console.log(Sethen.canSee()); //logs "Not blind"
Run Code Online (Sandbox Code Playgroud)
据我所知,使用Object.create创建继承的原型对象比使用new关键字要好得多.这引起了我脑子里的几个问题.
Male.prototype = Object.create(Human.prototype)将原型链Male.prototype --> Human.prototype --> Object.prototype --> null?Male我Human.call(this, eyes);用来调用超类的构造函数中,我必须在Male构造函数中再次传递眼睛以将其传递给Human构造函数.这似乎很痛苦,有没有更简单的方法呢?Male.prototype = new Human();...这似乎是不正确的.当我们这样做时,实际发生了什么?这两个原型继承实现之间有什么区别,并且考虑到我们正在使用2个不同的"原型"(仅在函数和内部原型上的原型属性),以及这些实现在原型链查找中有何不同?另外,第一个实现(使用prototype属性)是否依赖于我们对new运算符的使用?
分配给函数的prototype属性并使用new运算符:
function foo() {}
foo.prototype.output = function(){
console.log('inherits from Function.prototype property');
};
bar = new foo();
bar.output();
Run Code Online (Sandbox Code Playgroud)
将函数存储在对象文字中并使用该Object.create()方法:
var foo = {
output: function(){
console.log('inherits from the internal prototype');
}
};
var bar = Object.create(foo);
bar.output();
Run Code Online (Sandbox Code Playgroud) 我需要有关在Revealing Module Pattern方式中编写更好代码的建议.我已经按照教程http://weblogs.asp.net/dwahlin/archive/2011/09/05/creating-multiple-javascript-objects-when-using-the-revealing-module-pattern.aspx对我帮助很大了解这种模式的基础知识.我正在尝试创建基本图像滑块.请检查jsfiddle链接,
var Slider = window.Slider = window.Slider || {};
Slider = (function($){
var $reelWrap = $('.fnSlider'),
$reel = $('.fnSlider').children('ul'),
$slide = $reel.children('li'),
slideWidth = $slide.width(),
numSlides = $slide.length,
reelWidth = numSlides*slideWidth,
$prev = $('.prev'),
$next = $('.next'),
init = function(){
pageLoad();
nextSlide();
prevSlide();
},
pageLoad = function(){
var index = 2;
$reel.css('width', reelWidth);
$slide.eq(index).addClass('fnActive');
$reel.css('left', -(index*slideWidth));
}
nextSlide = function(){
$next.click(function(e){
e.preventDefault();
var index = $reel.children('.fnActive').index() + 1;
var scroll = index * slideWidth;
if(index …Run Code Online (Sandbox Code Playgroud) javascript ×9
inheritance ×3
ecmascript-5 ×2
prototype ×2
constructor ×1
ecma262 ×1
jquery ×1
performance ×1