javascript - Javascript 中的面向对象问题

标签 javascript oop

我已经使用 javascript 一段时间了,但从未学过超过基础知识的语言。我正在阅读 John Resig 的“Pro Javascript Techniques”——我提出了一些问题,但我没有在书中或谷歌等网站上找到这些问题的答案。

约翰在他的书中给出了这个例子:
函数#1

function User( name, age ){
  this.name = name;
  this.age = age;
}
// Add a new function to the object prototype
User.prototype.getName = function(){
  return this.name;
};
User.prototype.getAge = function(){
  return this.age;
};
var user = new User( "Bob", 44 );
console.log("User: " + user.getName() + ", Age: " + user.getAge());

我还在学习 prototype 属性,所以我试着写了类似的东西:
函数 #2

function User (name, age ) {
  this.name = name;
  this.age = age;
  this.getName = function() {
    return this.name;
  };
  this.getAge = function() {
    return this.age;
  };
}
var user = new User( "Bob", 44 );
console.log("User: " + user.getName() + ", Age: " + user.getAge());

它不使用 prototype 属性来创建 getName 和 getAge 函数,但输出与 John 的示例相同。

我更进一步,创建了这个:
函数#3

var User = {
  name: "",
  age: 0,
  setName: function(name) {
    this.name = name;
  },
  setAge: function(age) {
    this.age = age;
  },
  getName: function() {
    return this.name;
  },
  getAge: function() {
    return this.age;
  }
};
User.setName("Bob");
User.setAge(44);
console.log("User: " + User.getName() + ", Age: " + User.getAge());

同样 - 它看起来与 John 的示例不同(我必须添加 setter 方法),但输出是相同的。

问题 #1 - 这 3 个函数有什么区别? prototype 属性的优势是什么,函数 #2 做错了什么,因为它似乎更直接地指向代码 #2 而不是 #1(尽管我确信 #1 做得更好,因为 John 创建它) .

问题 #2 - 我如何修改函数 #3 以不使用 setName 和 setAge 方法,但仍然保留 {...} 速记? {...} 速记可以有构造函数吗?

在此先感谢您帮助我学习!

编辑 我认为我的第二个问题有点令人困惑。我的意思是如何使用 {...} 速记来创建一个 User 对象,但是在创建该对象之后,可以这样说:

var user = new User("Bob", 44);

就像功能 #1 中的一样 - 还是不可能?

编辑#2 哇!感谢大家的精彩回答。这真的让我更清楚了。因此,如果我理解正确的话,#1 和#2 之间的差别不会太大。如果我只创建一个“用户”对象——它们可能根本没有什么不同。但是,如果我的程序创建了许多用户对象,#1 很可能会更高效并且使用更少的内存,因为所有对象都将共享相同的功能。

我非常感谢所有出色的回答 - 谢谢!

最佳答案

每次计算 function() {} 时,都会创建一个新的函数对象。因此,在#1 中,所有用户对象都共享相同的 getName 和 getAge 函数,但在#2 和#3 中,每个对象都有自己的 getName 和 getAge 副本。所有不同的 getName 函数的行为都完全相同,因此您在输出中看不到任何差异。

{...} 简写一个构造函数。评估时,它会构造一个具有给定属性的新“对象”。当您运行“new User(...)”时,它会构造一个新的“User”。您碰巧创建了一个与用户具有相同行为的对象,但它们属于不同类型。

评论回复:

你不能,直接。您可以根据 #3 创建一个创建新对象的函数。例如:

function make_user(name, age) {
    return {
        name: name,
        age: age,
        getName: function() { return name; },
        getAge: function() { return age; },
    };
}

var user = make_user("Joe", "18");

关于javascript - Javascript 中的面向对象问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/444170/

相关文章:

Java 对某些对象使用相同的引用,但有时它会创建 2 个实例

javascript - 链接 map reduce 过滤器时如何减少迭代?

javascript - React.js 和 Firebase 如何在我的 bootstraptable 中显示数据

javascript - 发生构建错误 ReferenceError : describe is not defined > During now. sh 部署

java - 在Java中开发泛型修饰符的正确方法

c++ - 将基类的指针转换为继承类

javascript - vuex中的数据如何设置初始值?

javascript - 从javascript中的多个元素中删除相同的类

java - 何时创建辅助方法和单独的文件

php - 混合 PHP 和 HTML 时集成清洁代码