Javascript原型,对象,构造函数?我很困惑

3 javascript oop methods constructor class

我已经经历了大量有描述的Stack Overflow问题,但我认真地发现它们非常令人困惑.我想要的是一个简单的解释,请不要参考链接.

我完全糊涂了,完全混淆了:

  • 原型,

  • 对象,

  • 构造函数

我做了很多研究,但发现它们非常复杂.

任何简单的解释?

T.J*_*der 11

好的,旋风之旅:

对象

对象是具有属性的东西.属性具有名称和值.名称始终是字符串(尽管我们可以在大多数情况下不加引号地编写它们),并且值可以是JavaScript支持的任何值:数字,字符串,布尔值,null,未定义或对象的引用.

所以:

var a = {
    propertyName: "property value"
};
Run Code Online (Sandbox Code Playgroud)

a是一个引用一个对象的变量,它有一个名为的属性propertyName,其值是字符串"property value".

原型

一个对象(比如说obj)可以p在它后面有另一个对象(比方说),除非它有自己的属性和给定的名字,否则它会p借给obj它的属性obj.p原型的对象obj.通过一个例子,这是最容易理解的:

// Let's create an object `p` with a couple of properties, `x` and `y`
// This syntax is called an "object initializer" (aka "object literal")
var p = {
    x: "x on p",
    y: "y on p"
};

// Now, we'll create a new object, `obj`, using `p` as its prototype
var obj = Object.create(p);

// And that means if we ask `obj` for a property called `x`, since it doesn't
// have its **own** `x`, it asks `p` for it. (And the same with `y`)
console.log(obj.x); // "x on p"
console.log(obj.y); // "y on p"

// But we can give `obj` its *own* `x` instead if we want
obj.x = "x on obj";
console.log(obj.x); // "x on obj"
console.log(obj.y); // "y on p"

// Doing that to `obj` had no effect on `p`
console.log(p.x); // "x on p"
console.log(p.y); // "y on p"
Run Code Online (Sandbox Code Playgroud)

原型的一个非常非常重要的方面是对象之间的连接是实时的.因此,如果obj没有一个y物业,每次我们要求的时间objy它去和要求p.因此,如果我们改变p价值y,那么如果我们要求改变就会显示出来obj:

var p = {
    x: "x on p",
    y: "y on p"
};

var obj = Object.create(p);

console.log(obj.y); // "y on p"

p.y = "updated y on p";

console.log(obj.y); // "updated y on p"
Run Code Online (Sandbox Code Playgroud)

这种实时连接至关重要.所以再次想到这样:我们要求 obj财产y,并obj说"我没有自己的财产,所以我会去寻求p它并给你那个."

注意:Object.create我用来创建的函数obj是新的ECMAScript5(几年前的规范更新).我们将回到另一种方式给对象一个原型进一步向下.

对象的原型当前总是在创建对象时设置,并且无法更改(创建后我无法交换q而不是p上面的obj).上面我正在使用Object.create它(下面我们将讨论构造函数).在ECMAScript5(ES5)之前,没有标准方法来获取对象的原型.ES5为我们提供了一种方法,现在称之为Object.getPrototypeOf,但仍然没有提供改变它的方法.下一个版本ES6将会更进一步.

功能

函数是执行操作的代码单元.函数也是对象,因此它们可以具有属性,但在实践中,在函数上使用属性是相对罕见的(除了call和之外apply,我们在这里不需要讨论).

你可以声明一个函数:

function foo() {
}
Run Code Online (Sandbox Code Playgroud)

...或者您可以使用表达式创建一个:

// An anonymous -- unnamed -- function assigned to variable `foo`
var foo = function() {
};

// A function named `f` assigned to variable `foo`
var foo = function f() {
};
Run Code Online (Sandbox Code Playgroud)

声明和表达是不同的.在执行相同作用域中的任何分步代码之前,将评估函数声明.与所有其他表达式一样,函数表达式在逐步执行的代码中进行评估.(人们有时称之为"吊装",因为这意味着实际上,即使函数声明位于范围的底部,它也好像已被提升 - 悬挂 - 顶部.)

函数可以有参数:

// `a` and `b` are arguments
function sum(a, b) {
    console.log(a + b);
}
Run Code Online (Sandbox Code Playgroud)

他们可以有返回值:

function sum(a, b) {
    return a + b;
}
console.log(sum(1, 2)); // "3"
Run Code Online (Sandbox Code Playgroud)

如果函数没有返回其他内容,则调用该函数的结果就是值undefined.

方法

JavaScript没有方法.它只有功能 - 但这就是它真正需要的功能.但是如果你有一个分配给对象属性的函数,并且你将该函数作为从对象中检索属性的表达式的一部分来调用,那么会发生一些使得JavaScript 似乎有方法的事情:this关键字引用函数调用中的那个对象.再一次,一个例子可以创造奇迹:

// A blank object
var obj = {};

// Lets put a function on it as a property
obj.foo = function() {
    console.log("this is obj? " + this === obj);
};

// Let's call that function
obj.foo(); // "this is obj? true"
Run Code Online (Sandbox Code Playgroud)

更多关于我的博客:

构造函数

构造函数与new关键字一起使用,它们是为对象提供原型的方法之一.当您通过函数调用函数时new,会创建一个新对象,并从函数的prototype属性中分配一个原型:

function Foo() {
}
Foo.prototype.x = "x on Foo.prototype";

var obj = new Foo();
console.log(obj.x); // "x on Foo.prototype"
Run Code Online (Sandbox Code Playgroud)

每个函数都自动拥有一个prototype属性,即使我们当然不会将绝大多数函数用作构造函数.

这里需要注意的重要事项是:prototype函数的属性只是一个无聊的旧属性.除非通过new运算符调用该函数,否则它不是任何对象的原型.当您通过函数调用函数时,new运算符使用prototype函数的属性来设置新对象的原型new,但这就是全部.

值得一提的是,在ES5之前,像上面这样的构造函数是你用特定原型创建对象的唯一方法.但是通过ES5,我们得到Object.create了更多关于如何使用JavaScript的模式.(总是可以Object.create通过使用临时功能创建自己的,事实上这正是一些人所做的.)有些人不喜欢使用new关键字和prototype属性,他们更喜欢使用"构建器"模式你只需要调用一个函数并找回一个对象.JavaScript非常灵活,您可以这样做.


更多探索