我有点困惑用javascript学习所有新的ES6和ES5语法,当谈到带有方法的函数/类并调用那些方法时,我无法真正说出“正确的方法”。
例如,请使用以下代码:
function account(amount) {
let cash = amount;
this.setCash = function(amt)
{
cash = amt;
}
this.getCash = function()
{
return cash;
}
}
var person = new account(100);
console.log(person.getCash()); //returns 100
person.setCash(150);
console.log(person.getCash()); //returns 150
按预期正常工作(这是我最初看到教程中使用的方法)。
但是我偶尔会看到这个:
function account2(amount) {
let cash = amount;
function setCash(amt)
{
cash = amt;
}
function getCash()
{
return cash;
}
return{
getCash,
setCash
}
}
var person2 = new account2(50);
console.log(person2.getCash()); //returns 50
person2.setCash(175);
console.log(person2.getCash()); //returns 175
这两种方法都非常好,而且我认为应该这样做。然而,这只是一种较老的方式吗?或者更不正确?这是我现在学习JS的最大障碍,因为ES6在这里有很多不同的方法来做一些简单的事情,就像在JS中用方法制作一个“类”一样简单。
就个人而言,第一种方式似乎更容易,因为你不必返回函数....但是例如在工作中我看到第二种方式主要使用?
答案 0 :(得分:4)
如果您从第二个版本中删除new
(稍后会详细介绍),那么您的两个示例都是使用公共get / set方法访问私有数据的完美对象。您选择哪一个是个人偏好,或者取决于您是否希望通过原型方法进一步扩展功能等。
我建议从第二个版本中删除new
的原因是,虽然两个示例都有效,但第一个是"正常"使用the new
operator,但第二个是"不正确"使用new
运算符 - 不是语法错误,只是在语义上不正确,并且可能会误导其他人阅读您的代码。
那么为什么第二次使用new
在语义上不正确?当你说var person = new account(100)
时:
account.prototype
原型创建新对象。这意味着新对象继承了account.prototype
的任何方法和属性,以及其原型等等。(在您的情况下,您还没有在原型上定义任何方法,但是你可以。)account()
函数中,this
将引用在步骤1中创建的对象。这就是您可以使用this.setCash = ...
account()
会返回新对象。如果有明确的return
语句返回您的account2()
函数中的其他内容,则此步骤不会。因此,在第一个示例中,person instanceof account
为true
,因为返回了默认对象。在第二个示例中,person2 instanceof account2
为false
,因为返回了另一个对象 - 这对于阅读代码的人来说会产生误导,因为当他们看到person2 = new account2()
时,他们可能会合理地期望{{1}将是person2
的一个实例,但它不是。它的效率也有点低,因为JS引擎会为您创建一个对象,然后您就不会使用它。
所以第二个例子会更多"正确"没有account2
,提供相同的行为减去不必要的自动对象创建:
new
(几乎)你用var person2 = account2(50);
调用可以调用的任何JS函数,但是有一个约定,我们描述要调用的函数 new
作为"构造函数",通常函数名称大写,因此new
,而不是Account()
。 (拼写不会改变行为,它只是人们阅读代码的额外提示。)
请注意,使用account()
并不是将对象链接到特定原型的唯一方法:它是旧式但仍然完美有效的方式,但您可以使用{{3相反。
顺便说一下,虽然new
let
中的快捷方式对象文字语法是新的,但有问题的行为在ES5或6中并不新鲜。
答案 1 :(得分:2)
当您使用new
关键字this
创建实例时会隐式返回,而在将函数指定给没有new
的变量时,您需要显式使用return
。