使用'new'关键字创建JavaScript对象

时间:2013-08-04 06:09:05

标签: javascript object

我正在学习JavaScript并与其Object概念混淆。我曾经是一名Java程序员,我很害怕JavaScript没有类。 从我到目前为止学到的,函数可以替代JavaScript中的类。您可以使用如下所示的“new”关键字来实例化该功能。

function person() {
    var name;
    this.tellYourName = function() {
        return 'My name is ' + name;
    }
    this.setName = function(newName) {
        name = newName;
    }
}

var person1 = new person();

person1.setName('Chris');
alert(person1.tellYourName());

在上面的代码中,我创建了一个对象'person1',继承了person函数的属性。

所以这是我的问题。 是person()一个对象?我的意思是对象是person()是一个类还是一个实例化的对象。

当我研究关闭时,我对这个概念感到困惑。 这是示例代码

function closureTest(a) {
    return function(b) {
        return a + b;
    }
}

var test = closureTest(1);
alert(test(2));

这里我认为closureTest函数可以作为方法而不是类。并且var test = closureTest(1);行未使用“new”关键字。这意味着测试变量将存储closureTest(1);的返回值但是正如您所见,测试变量被用作closureTest的对象。这怎么可能?因为当我尝试使用下面的测试代码时

function test(a) {
    return a;
}
var t = test(2);
alert(t);

按照我的预期打印出测试函数的返回值。

我希望我的问题不会太混乱。我目前从Java转向JavaScript,我认为它们几乎完全一样都是错的。我在JavaScript中阅读了几个关于对象概念的讲座,但它更令人困惑。 感谢您花时间阅读本文,希望我能从您那里得到一些东西:)

5 个答案:

答案 0 :(得分:3)

一些理论观察:)

对象是类的实例化这一概念对理解JavaScript非常有帮助。 JavaScript涉及原型继承,而不是经典继承。换句话说,对象从继承链的上方继承其他对象的属性,但不从类继承属性。

首先,函数是JavaScript中的对象。这意味着函数可以有方法。

其次,如果使用new前缀调用函数,则会创建一个新对象。这个新对象将链接到函数的原型,但this将引用新对象。旨在与new一起使用的函数称为constructors

第三,有各种方法可以实现同样的目标。所以你可以这样做:

// The capital for the function indicates a constructor function
function Person(name) {
    this.name = name;
}
Person.prototype.tellYourName = function() {
    return 'My name is ' + this.name;
};
Person.prototype.changeName = function(newName) {
    this.name = newName;
};    
var person1 = new person("Chris"),
    random_string = person1.tellYourName(); // Chris

或者,您可以在不使用new的情况下实现相同的目标。

function person(name) {
    // myName is a private variable
    var myName = name; // This line is actually unnecessary if you use name throughout

    return {
        // Public methods
        tellYourName: function() {
            return 'My name is ' + myName;
        },
        setName: function(newName) {
            myName = newName;
        }
    }
}
var person1 = person("Chris"); // Note that `new` is not used

后者通常是首选,因为它附带了数据隐藏。换句话说,获取属性name的唯一方法是使用公共方法。

答案 1 :(得分:3)

我理解你的困惑。 Java和JavaScript唯一的共同点是类似C语法和名称。除此之外,Java和JavaScript是两种截然不同的编程语言:

  1. Java是一种经典的面向对象编程语言。 JavaScript是prototypal object-oriented programming language
  2. 在Java中,函数必须是类的方法。在JavaScript中,函数是first-class citizens。这使JavaScript比Java强大得多。
  3. Java将其祖先追溯到C / C ++。 JavaScript将其祖先追溯到Self和Scheme。
  4. 与Java不同,JavaScript不仅是一种面向对象的编程语言,也是一种函数式编程语言(尽管不像Haskell或OCaml那样功能)。因此,函数在JavaScript中起着重要作用。

    JavaScript中的函数可用于:

    1. 创建对象的模板(即表现得像一个类)。
    2. 封装状态和行为(即表现得像namespace)。
    3. 分享功能并减少冗余(即表现得像mixin)。
    4. 作为类

      的功能

      JavaScript没有类,因为它是一种原型的面向对象的编程语言。不幸的是,prototypal nature of JavaScript隐藏在构造函数后面,使它看起来更像Java。但是,这只会让Java程序员难以理解JavaScript中的继承。

      例如,假设您在Java中有以下Rectangle类:

      public class Rectangle {
          public int width;
          public int height;
      
          public Rectangle(int width, int height) {
              this.width = width;
              this.height = height;
          }
      
          public int area() {
              return this.width * this.height;
          }
      }
      

      在JavaScript中,您可以按如下方式编写以上内容:

      function Rectangle(width, height) {
          this.width = width;
          this.height = height;
      }
      
      Rectangle.prototype.area = function () {
          return this.width * this.height;
      };
      

      如果您不喜欢这种语法,那么您可以使它看起来更像一个类,如下所示:

      function CLASS(prototype) {
          var constructor = prototype.constructor;
          constructor.prototype = prototype;
          return constructor;
      }
      
      var Rectangle = CLASS({
          constructor: function (width, height) {
              this.width = width;
              this.height = height;
          },
          area: function () {
              return this.width * this.height;
          }
      });
      

      我编写了一个名为augment的函数,可以让您的生活更轻松。

答案 2 :(得分:2)

首先关注新关键字。可以这样想:无论你在函数体中的this存储的个人函数,都会在创建新实例时传递。 所以新的Person()返回this以及您在this

上设置的任何函数

关于第二个问题,将其视为返回另一个函数的函数。它返回一个函数,而不是一个对象。功能在技术上是一个对象。因此,当您致电closuretest(1)时,您基本上会返回

var test=  function(b) {
    return 1+b;
 }

所以现在如果你调用test(2)它将返回1 + 2 = 3

希望有所帮助

答案 3 :(得分:0)

您上面显示的示例是两个不同的用例。在 javascript 中,每件事都被视为一个对象。当您为函数使用new关键字时,您的函数Object被视为一个类,而 this 引用的变量是您的类的属性,例如。

var Person = function(){
    this.name = null;
    this.age = 0;
};

这被视为Person Class ,其名称和年龄作为其属性,可用于类的实例/对象,并将对象创建为

var someone = new Person();
//someone.name and someone.age are valid then.

但是如果不在函数内使用这个,则不会将其创建为类,因此它将作为普通函数,如example2中所示,它返回了另一个可以使用的对象/函数。 有关此问题的更多说明,请阅读Object oriented javascript以及有关此主题的更多链接。

答案 4 :(得分:0)

当您在JavaScript中使用“new”关键字时,它会执行几个步骤。首先,它创建了一个具有所提供函数原型的Object的新实例,在您的情况下是它的人。第二步是使用新创建的对象的有界上下文调用提供的函数。最后一步是返回一个新创建的对象。因此,对象创建的神奇之处在于new运算符。你可以阅读它here