编写JS原型时,所有函数都应该使用原型对象
Writing JS Prototypes, should all functions use the Prototype object?
我开始学习更多关于使用Prototype对象编写JS的知识,但我想确保我不会从其他开发人员那里养成任何坏习惯。我对使用Prototype的理解是为您的实例创建公共方法。例如:
var module = new Module();
module.method();
但我看到很多开发人员在Prototype对象中创建他们所有的代码,我认为这些东西是"私有的"。这是一种糟糕的做法还是被认为是可以的?这只是意味着我可以做:
module.privateFn();
他们知道吗?这样可以吗?感谢您的帮助。我一直在查看GitHub上的源代码,试图建立最佳的前进道路,这里有一个脚本,它对所有事情都使用原型(例如attachEvent,他们显然希望私下保存):
https://github.com/WickyNilliams/headroom.js/blob/master/dist/headroom.js
非常感谢,我想确保我使用正确的实现进行开发。
首先,您不需要使用原型编写模块。想一想,如果你写的东西像一个类,你应该使用原型。在哪里定义方法也很重要。在原型对象上定义方法和在构造函数中定义方法是完全不同的!
让我们看看一个使用构造函数中定义的方法的示例类定义:
var Dog = (function () {
var Dog = function (age, name) {
var that = this;
this.age = age;
this.name = name;
this.sayHi = function () {
console.log('Warf! Im ' + that.name); // meaning of "this" changed!!!
};
this.anotherMethod = function () {};
};
return Dog;
}());
var puppy = new Dog(1, 'puppy'); // sayHi and anotherMethod created
var sirius = new Dog(1, 'sirius'); // sayHi and anotherMethod recreated
sirius.sayHi = function () { console.log('Yohalolop!'); };
puppy.sayHi(); // -> 'Warf! Im puppy'
sirius.sayHi(); // -> 'Yohalolop!'
因此,上面的例子存在一些问题,首先,方法的定义与任何其他实例变量一样。实际上,是的,您将它们定义为实例变量,这意味着为您创建的每个实例对象都会重新创建这些函数。我想您已经提到,在方法定义中不能使用这个关键字。这很容易出错,有可能会忘记这一点,并错误地使用This关键字。有时,您可以使用方法作为实例变量,当然也可以使用变量回调。
让我们看一个带有原型对象的示例类定义:
var Dog = (function () {
var Dog = function (age, name) {
this.age = age;
this.name = name;
};
// sayHi method defined only once in prototype
Dog.prototype.sayHi = function () {
console.log('Warf! Im ' + this.name; // we can use this keyword
};
// anotherMethod defined only once in protoype
Dog.prototype.anotherMethod() {
};
return Dog;
}());
var puppy = new Dog(1, 'puppy');
var sirius = new Dog(1, 'sirius'); // sirius and puppy sharing same prototype object
puppy.sayHi(); // -> 'Warf! Im puppy'
sirius.sayHi(); // -> 'Warf! Im sirius'
// remember puppy and sirius sharing same prototype object
Dog.prototype.sayHi = function () {
console.log('Yohalolop');
};
puppy.sayHi(); // -> 'Yohalolop'
sirius.sayHi(); // -> 'Yohalolop'
作为对您关于私有函数的问题的回答,它更为复杂。是的,即使在原型上定义方法,也可以使用私有函数,但在测试方面存在一些问题。它们的使用取决于你。我宁愿不用。让我举几个例子。
var Calculator = (function () {
var Calculator = function () {
this.importantNumber = 2;
};
// There is unfortunately no native implementation
// for private methods but you can mimic them with
// unaccessible functions and binding.
var someExtremeComputations = function () {
return 40 + this.importantNumber; // this keyword points to instance because of binding
};
Calculator.prototype.getMeaningOfLife = function () {
var result = someExtremeComputations.call(this); // we bind function to instance
return result;
};
return Calculator;
}());
这是如何在javascript中定义私有方法的示例之一。私有函数的问题,它们无法测试。没有办法测试某些ExtremeComputations方法。
有些人(包括我)对私有方法使用带前缀的下划线命名约定。因此,它们实际上是公共方法,但如果有人调用或重写它们,则会使用带前缀的下划线进行警告。毕竟,我们可以测试私有方法,因为它们是真实的公共方法。
var Calculator = (function () {
var Calculator = function () {
this.importantNumber = 2;
};
// private method's name prefixed by an underscore to warn
// other developers to be careful about that or not to use.
Calculator.prototype._someExtremeComputations = function () {
return 40 + this.importantNumber;
};
Calculator.prototype.getMeaningOfLife = function () {
var result = this.someExtremeComputations(); // no need to bind
return result;
};
return Calculator;
}());
用几个字来解释这一点是不可能的。当您想要优化代码时,一个通常好的模式是通过原型构建方法。一个好的指导原则是只将最重要的数据放在内存中,使用原型对这一点至关重要,因为原型化的变量和方法在您请求之前不会注入内存。
当谈到你的例子时,没有原型。
的简单示例
// new object
var Dog = function() {
var that = this;
// add a property
that.name = "Fido";
// add a method
that.getName = function() {
return that.name;
};
};
// ... all the above is stored in memory directly
// Requires to be constructed
var dogObj = new Dog();
console.log(dogObj.getName()); // Fido
delete Dog.name // false
typeof Dog.name // "string"
delete dogObj.name // true
typeof dogObj.name // "undefined"
typeof Dog.name // "string" (still there)
// Will be available in the dogObj (after you call it)
dog.prototype.first = "first";
// Will be available in the dogObj (after you call it)
dog.prototype.second = function() {
return "second";
}
// Will not be available in dogObj
dog.third = "third";
- Node.js中的JavaScript原型对象效率
- 获取原型对象的名称
- 如何维护对原型对象的访问
- 文字与原型对象表示法的数据结构
- 使用原型对象向javascript对象添加自定义属性和方法的建议
- 正在重置原型对象的构造函数属性
- 编写JS原型时,所有函数都应该使用原型对象
- 什么's是原型对象的真实名称
- Javascript - 使用数组作为函数的参数,并在创建新的原型对象时更改值
- 在原型对象 jquery 上将一个按钮与另一个按钮不同
- 原型对象
- 循环遍历数组时的原型对象
- 为什么初始化的 JavaScript 对象不包含原型对象
- JavaScript 原型对象 - 如何访问继承
- Javascript:获取此原型对象名称
- 如何在数据绑定后在 KNOCKOUT js 中使用“with”访问另一个原型对象
- 这在 JavaScript 中的原型对象中的值
- 在主干中向原型对象添加值不起作用
- 删除函数原型对象
- 为什么当我在这个JavaScript对象上使用反射时,我可以'看不到在其原型对象中定义的属性