3

我正在学习 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 中对象概念的讲座,但它变得更加混乱。感谢您花时间阅读本文,希望我能从您那里得到一些东西:)

4

5 回答 5

3

A few theoretical observations :)

The notion that an object is an instantiation of a class is pretty unhelpful for understanding JavaScript. JavaScript involves prototypal inheritance, not classical inheritance. In other words, objects inherit properties from other objects further up the inheritance chain, but not from a class.

First, functions are objects in JavaScript. This means that functions can have methods.

Second, if a function is invoked with the new prefix, then a new object is created. This new object will be linked to the function's prototype, but this will refer to the new object. Functions designed to be used with new are called constructors.

Third, there are various ways to achieve the same thing. So you can do this:

// 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

Alternatively, you can achieve the same thing without using 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

The latter is usually preferred because of the data hiding that comes with it. In other words, the only way to get at the property name is using the public methods.

于 2013-08-04T06:23:55.150 回答
3

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

  1. Java 是一种经典的面向对象的编程语言。JavaScript 是一种原型的面向对象的编程语言
  2. 在 Java 中,函数必须是类的方法。在 JavaScript 中,函数是一等公民。这使得 JavaScript 比 Java 更强大。
  3. Java 可以追溯到 C/C++。JavaScript 可以追溯到 Self 和 Scheme。

与 Java 不同,JavaScript 不仅是一种面向对象的编程语言,而且还是一种函数式编程语言(尽管不如 Haskell 或 OCaml 功能强大)。因此,函数在 JavaScript 中扮演着重要角色。

JavaScript 中的函数可用于:

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

作为类的函数

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

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

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它可以让你的生活更轻松。

于 2013-08-04T06:49:40.470 回答
2

First on the new keyword. Think of it this way: whatever you stored on this during the function body in person function, is passed when a new instance is created. So new Person() returns this and whatever functions you have set on this

On your second problem, think of it as a function returning another function. It is returning a function, not an object. A functions is technically an object. So when you call closuretest(1), you are basically returning

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

so now if you call test(2) it becomes return 1+2 =3

Hope that helps

于 2013-08-04T06:14:48.463 回答
0

The examples your have shown above are two different use cases. In javascript every thing is treated as an Object. When you were using the new keyword for a function then your function Object is treated as a Class and the variable referred with this are your properties of class e.g.

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

This is treated a Person Class with name and age as its properties which will be available with the instance/Object of the class Person and Object is created as

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

But if not using this inside the function does not create it as a class thus it acts as a normal function as shown in your example2 which was returning another object/function which can be used. For more clarification on this matter your should read Object oriented javascript and some more links on this topic.

于 2013-08-04T06:25:10.930 回答
0

When you use a 'new' key word in JavaScript it performs several steps. First of all it's creates a new instance of Object with prototype of provided function, in your case it's person. Second step is calling a provided function with bounded context of newly created object. The last step is returning a newly created object. So the magic of object creation is all in a new operator. You can read about it here

于 2013-08-04T06:28:35.287 回答