简体   繁体   English

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

[英]JavaScript Object creation with the 'new' keyword

I am studying JavaScript and being confused with its Object concept. 我正在研究JavaScript并与其Object概念混淆。 I used to be a Java programmer and it is terrifying me that JavaScript does not have class. 我曾经是一名Java程序员,我很害怕JavaScript没有类。 From what I've learnt so far, function can replace class in JavaScript. 从我到目前为止学到的,函数可以替代JavaScript中的类。 and you can instantiate the function by using the ' new ' keyword like below. 您可以使用如下所示的' 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());

in the code above, I created an object 'person1' inheriting the properties from person function. 在上面的代码中,我创建了一个继承person函数属性的对象'person1'。

So here's my question. 所以这是我的问题。 is person() an object? 是person()一个对象? what I meant by object is whether the person() is a class or an instantiated object. 对象的意思是person()是类还是实例化对象。

I was confused with this concept when I was studying closure. 当我研究闭合时,我对这个概念感到困惑。 Here's the sample code 这是示例代码

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

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

Here I guess the closureTest function works as a method not a class. 在这里,我认为closureTest函数作为一个方法而不是一个类。 and var test = closureTest(1); var test = closureTest(1); line did not use the ' new ' keyword. line没有使用' new '关键字。 That means test variable will store the return value from the closureTest(1); 这意味着测试变量将存储来自closureTest(1);的返回值closureTest(1); But as you see the test variable is used as a an object of closureTest . 但正如您所见,测试变量被用作closureTest的对象。 How is this possible? 这怎么可能? because when I tried it with the test code below 因为当我尝试使用下面的测试代码时

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

prints out the return value of the test function as I expected. 按照我的预期打印出测试函数的返回值。

I hope my question is not too confusing. 我希望我的问题不会太混乱。 I currently moved from Java to JavaScript and my thought that they will be almost same is all wrong. 我目前从Java转向JavaScript,我认为它们几乎完全一样都是错的。 I read several lectures about Object concept in JavaScript but it get even more confusing. 我在JavaScript中阅读了几个关于对象概念的讲座,但它更令人困惑。 Thanks for your time reading this and hope I can get something from you :) 感谢您花时间阅读本文,希望我能从您那里得到一些东西:)

A few theoretical observations :) 一些理论观察:)

The notion that an object is an instantiation of a class is pretty unhelpful for understanding JavaScript. 对象是类的实例化这一概念对理解JavaScript非常有帮助。 JavaScript involves prototypal inheritance, not classical inheritance. JavaScript涉及原型继承,而不是经典继承。 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. 首先,函数是JavaScript中的对象。 This means that functions can have methods. 这意味着函数可以有方法。

Second, if a function is invoked with the new prefix, then a new object is created. 其次,如果使用new前缀调用函数,则会创建一个新对象。 This new object will be linked to the function's prototype, but this will refer to the new object. 这个新对象将被链接到该函数的原型,但是this将引用新的对象。 Functions designed to be used with new are called constructors . 设计用于newconstructors称为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 . 或者,您可以在不使用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. 换句话说,获取属性name的唯一方法是使用公共方法。

I understand your confusion. 我理解你的困惑。 The only thing that Java and JavaScript have in common is C-like syntax and the name. Java和JavaScript唯一的共同点是类似C语法和名称。 Other than that Java and JavaScript are two very different programming languages: 除此之外,Java和JavaScript是两种截然不同的编程语言:

  1. Java is a classical object-oriented programming language. Java是一种经典的面向对象编程语言。 JavaScript is a prototypal object-oriented programming language . JavaScript是一种原型的面向对象编程语言
  2. In Java functions must be methods of a class. 在Java中,函数必须是类的方法。 In JavaScript functions are first-class citizens . 在JavaScript中,函数是一等公民 This makes JavaScript much more powerful than Java. 这使得JavaScript比Java强大得多。
  3. Java traces its ancestry to C/C++. Java将其祖先追溯到C / C ++。 JavaScript traces its ancestry to Self and Scheme. JavaScript将其祖先追溯到Self和Scheme。

Unlike Java, JavaScript is not only an object-oriented programming language but also a functional programming language (although not as functional as Haskell or OCaml). 与Java不同,JavaScript不仅是面向对象的编程语言,而且是一种函数式编程语言(尽管不像Haskell或OCaml那样功能)。 Hence functions play a major role in JavaScript. 因此,函数在JavaScript中起着重要作用。

Functions in JavaScript may be used to: JavaScript中的函数可用于:

  1. Create a template of an object (ie behave like a class). 创建对象的模板(即表现得像一个类)。
  2. Encapsulate state and behavior (ie behave like a namespace ). 封装状态和行为(即行为像命名空间 )。
  3. Share functionality and reduce redundancy (ie behave like a mixin ). 共享功能并减少冗余(即表现得像mixin )。

Functions as classes 作为类的功能

JavaScript doesn't have classes because it's a prototypal object-oriented programming language. JavaScript没有类,因为它是一种原型的面向对象的编程语言。 Unfortunately the prototypal nature of JavaScript is hidden behind constructors to make it look more like Java. 遗憾的是,JavaScript原型性质隐藏在构造函数之后,使其看起来更像Java。 However this only makes it difficult for Java programmers to understand inheritance in JavaScript. 但是,这只会让Java程序员难以理解JavaScript中的继承。

For example, say you have the following Rectangle class in Java: 例如,假设您在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;
    }
}

In JavaScript you would write the above as follows: 在JavaScript中,您将按如下方式编写以上内容:

function Rectangle(width, height) {
    this.width = width;
    this.height = height;
}

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

If you don't like this syntax then you can make it look more like a class as follows: 如果您不喜欢这种语法,那么您可以使它看起来更像一个类,如下所示:

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;
    }
});

I have written a function called augment which may make your life easier. 我写了一个名为augment的函数,可以让你的生活更轻松。

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. 想想这样说:无论你存储在this亲自函数的函数体中,创建一个新的实例时传递。 So new Person() returns this and whatever functions you have set on this 所以新的Person()会返回this以及你在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 所以当你调用closuretest(1) ,你基本上都会回来了

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

so now if you call test(2) it becomes return 1+2 =3 所以现在如果你调用test(2)它将返回1 + 2 = 3

Hope that helps 希望有所帮助

The examples your have shown above are two different use cases. 您在上面显示的示例是两个不同的用例。 In javascript every thing is treated as an Object. javascript中 ,每件事都被视为一个对象。 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 eg 当您为函数使用new关键字时,您的函数Object被视为一个类,并且与一起引用的变量是您的类的属性,例如

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 这被视为Person ,其名称和年龄作为其属性,可用于类的实例/对象Person和Object被创建为

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. 但是,如果不使用函数内部如所示的示例2将其返回另一个目的/功能可使用的一类因此它作为一个正常的功能不创建它。 For more clarification on this matter your should read Object oriented javascript and some more links on this topic. 有关此问题的更多说明,您应阅读面向对象的javascript以及有关此主题的更多链接。

When you use a ' new ' key word in JavaScript it performs several steps. 当您在JavaScript中使用“ new ”关键字时,它会执行几个步骤。 First of all it's creates a new instance of Object with prototype of provided function, in your case it's person. 首先,它创建了一个具有所提供函数原型的Object的新实例,在您的情况下是它的人。 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. 因此,对象创建的神奇之处在于一个new运算符。 You can read about it here 你可以在这里阅读它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Javascript对象创建与此关键字和prototype属性的混淆 - Javascript object creation confusion with this keyword and prototype property 使用'Object.create()'而不是'new'关键字来理解原型对象的创建 - Understanding prototype object creation with 'Object.create()' instead of 'new' keyword 使用new关键字时与创建对象的过程混淆 - Confusion with process of creation an object when we use new keyword javascript 初始化一个没有 new 关键字的对象 - javascript init an object without the new keyword new关键字,Javascript中的new Object()和Object.create() - new keyword, new Object() and Object.create() in Javascript 在anthor对象中使用Object方法,而不在javascript中使用new关键字 - Use Object method in anthor object without using new keyword in javascript 如何在javascript中为一个带有new关键字的对象提供一个属性和一个方法? - How to give a property and a method to one object that's with the new keyword in javascript? 与“ new”关键字一起使用时,Object函数在Javascript中有什么作用? - What does the Object function do in Javascript when used with the “new” keyword? 为什么Math Object在javascript中不需要新的关键字 - Why Math Object does not need new keyword in javascript 我可以在不使用 new 关键字的情况下构造 JavaScript 对象吗? - Can I construct a JavaScript object without using the new keyword?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM