阅读来自Crocksford的'Javascript好部分',我一直在寻求编写一些高效,可读和可重用的 JavaScript代码。 这就是我的目标,特别是对象的属性是公开的。
话虽如此,代码是否有任何特定的问题或改进点?
( function(){
window.App = {}
// define uma pessoa normal
App.Person = function(name){
this.name = name || "anon"
this.iq = 100
this.fortune_number = Math.floor(Math.random()*100)
}
App.Person.prototype.sayName = function() {
return (this.name+"!")
}
App.Person.prototype.sayIQ = function() {
return (this.iq)
}
// define um genio da humanidade
App.Genius = function(name) {
App.Person.call( this, name )
this.iq = 9000
};
// inherits All methods from Pessoa
App.Genius.prototype = App.Person.prototype
App.Genius.prototype.solveNP = function() {
return "eureka!"
};
})()
var p = new App.Person('Jon')
console.log( "A Person:", p.sayName(), p.fortune_number, p.sayIQ() )
//-> A Person: Jon! 10 100
var g = new App.Genius( 'Eugenios' )
console.log( "A Genious:", g.sayName(), g.fortune_number, g.sayIQ(), g.solveNP() )
//-> A Genious: Eugenios! 7 9000 eureka!
我特别不确定此行App.Genius.prototype = App.Person.prototype
是否合适,因为我通常会在某些新实例之后看到原型,例如Mozilla Guide
答案 0 :(得分:2)
您的代码中没有真正的继承。你必须扩展原型链才能拥有真正的(原型)继承。
// This is how it's done in JS
Child.prototype = new Parent();
Child.prototype.constructor = Child;
这有执行Parent构造函数的副作用,在某些情况下这可能是坏的(例如,如果构造函数需要任何参数)。您应该使用以下位来进行继承。
var Fn = function () {}; // empty constructor, no side-effects
Fn.prototype = Parent.prototype;
Child.prototype = new Fn();
Child.prototype.constructor = Child;
答案 1 :(得分:1)
否则
App.Genius.prototype = App.Person.prototype
不是一个好主意:
var Parent = function (name) {
this.name = name;
}
Parent.prototype.greet = function (who) {
alert(name + ' say hi to ' + who);
}
var Child = function () {
}
Child.prototype = Parent.prototype;
Child.prototype.shout = function (you) {
alert('HEEEEY '+ you);
}
var c = new Child();
c.shout('Joe');
var p = new Parent('Joe');
p.shout('Jimmy');
请参阅此in action 。
此提醒HEEEEY Joe
和HEEEY Jimmy
。
父母和孩子都会获得相同的prototype
对象。实际上,您可以覆盖父级的prototype
。
通常最好为childs原型添加一个实例:
Child.prototype = new Parent();
但是,这会导致Parent
的{{1}}参数丢失,更重要的是执行构造函数。通常所做的是在中间放置一个空函数。将它包装在实用程序中是个好主意。
name
用法:
var hasProp = Object.prototype.hasOwnProperty,
extend = function(child, parent) {
# Copy the class-level attributes (static in Java)
for (var key in parent) {
if (hasProp.call(parent, key)) child[key] = parent[key];
}
# Create the middle man
function ctor() {
this.constructor = child;
}
# Use parent's prototype and DON'T modify it
ctor.prototype = parent.prototype;
# Assign an instance to child's prototype, so modifications
# to it are not reflected up the inheritance chain
child.prototype = new ctor;
# Simple convenience attribute to know your super class
child.__super__ = parent.prototype;
return child;
};
答案 2 :(得分:0)
以下是我使用自制继承库创建伪类的方法:
//Namespace, ie global. could be "MyNamespace.MyClass"...
Class( "MyClass", HisClass, /* List of classes to inherit from/interfaces to implement */, {
MyClass: function( name ) { //Constructor
this.name = name;
}
"final override sayHello": function(){ //there is no implicit overriding
alert( "hello from " + this.name );
},
"static create": function( name ) {
return new this( name ); //this refers to constructor in static method
}
});
然后您将实例化该类:
var a = new MyClass( "john" );
或
var a = MyClass.create( "john" );
我只实现了伪语“final”,“static”和“override”。我不知道它是否好,但它对我有用。但正如你所看到的,我并不担心那里的原型,所以如果你想创建一个伪古典库但是在你上课时必须使用原型,那么在我看来它不是那种伪古典。
答案 3 :(得分:-1)
我只想添加一个私有字段:
var that = this;
在您的所有方法中,使用that
代替this
。