详细了解 JavaScript:它是一个 class、一个函数,还是只是一个变量?
Understanding JavaScript in detail: is it a class, a function, or just a variable?
我是 JavaScript 的初学者,我发现一个概念非常混乱。考虑以下代码:
var person = {
firstName :"Penelope",
lastName :"Barrymore",
// Since the "this" keyword is used inside the showFullName method below, and the showFullName method is defined on the person object,
// "this" will have the value of the person object because the person object will invoke showFullName ()
showFullName:function () {
console.log (this.firstName + " " + this.lastName);
}
}
person.showFullName (); // Penelope Barrymore
人是 class 还是函数还是只是一个变量?
如果假设那个人是 class,代码 person.showFullName ();
是调用它的正确方法吗,因为在 C# 或我们编写的任何其他语言中
person perObj = new person();
perObj.showFullName();
?
person
是一个对象。它有 3 个属性,名为 firstName
、lastName
和 showFullName
。前两个属性包含字符串。最后一个 属性 包含一个函数。
当您使用语法 <expression>.<function>(<arguments>)
调用函数时,其中 <expression>
求值为一个对象,而 <function>
是其属性之一的名称,那么当函数是 运行 特殊变量 this
被设置为对象。这就是 this.firstName
和 this.lastName
能够访问对象的那些属性的方式。
当只有一个对象时,此功能不是很有用,因为它可以很容易地只使用 person
变量。但是您可以对多个对象使用相同的函数。
function showFull() {
console.log(this.firstName + " " + this.lastName);
}
var person1 = {
firstName: "Penelope",
lastName: "Barrymore",
showFullName: showFull
};
var person2 = {
firstName: "John",
lastName: "Smith",
showFullName: showFull
}
person1.showFullName(); // Penelope Barrymore
person2.showFullName(); // John Smith
JavaScript 没有 类 或者不是 class-based 语言。相反,我们说它是一种 prototype-based 语言。
补充一下 Barmar,您也可以这样做(以防您发现它更类似于 C#):
var person = function() {
this.firstName = "";
this.lastName = "";
}
person.prototype.showFullName = function () {
console.log (this.firstName + " " + this.lastName);
}
var perObj = new person();
perObj.firstName = "Penelope";
perObj.lastName = "Barrymore";
perObj.showFullName();
它是一个对象,而不是 class。
这样想:
在其他 classical OO 语言中,当您实例化 class 时,
你得到一个实例;这个实例相当于 JavaScript object -
JavaScript 对象是动态的 "bags" 属性。它是一组 name-value 对,这些值可以是任何类型 - 函数或对象本身。
在你的例子中,firstName, lastName, and showFullName
是 person 对象的属性。
您使用点 (.) 表示法访问对象的属性,
例如:person.firstName, person.showFullName()
person
实际上是JavaScript中的一个对象字面量。对象文字是那些被定义为
var obj = {
// Properties and methods
};
并且它们的类型是对象。在 JavaScript 中我们没有任何叫做 class 的东西。
- 一切都是对象。 (偶函数)
An object literal is a comma-separated list of name-value pairs wrapped in curly braces. Object literals encapsulate data, enclosing it in a tidy package.
http://www.dyn-web.com/tutorials/object-literal/
虽然我们在 ECMAScript 6 中确实有 classes,但它们并不像其他语言中那样真实 classes。
MDN 说:
JavaScript classes are introduced in ECMAScript 6 and are syntactical
sugar over JavaScript's existing prototype-based inheritance. The
class syntax is not introducing a new object-oriented inheritance
model to JavaScript. JavaScript classes provide a much simpler and
clearer syntax to create objects and deal with inheritance.
Is person a class or function or just a variable?
JavaScript 没有 类。变量 person 是指向保存对象的内存位置的变量。
对象本身有几个方面。有一组附加的属性都附加到 person 对象。其中一个属性包含一个值,它是函数对象。这个函数对象包含一个执行上下文。
Execution ContextECMA 有本地环境、词法环境和 this 绑定。 this 绑定指向 person 对象。函数的局部环境限定为函数内部的声明,函数的词法环境限定为可用于 Person 对象的声明。
person
在您的代码中是一个 object
。也就是说,person
是Object
的实例,person
原型和其他对象中的原型一样,由{}
初始化器创建:
// Object initialiser or literal
person = {
some methods and properties
}
// Called as a constructor
person = new Object({some methods and properties})
这意味着你的person
对象从原型继承对象特定的方法,例如hasOwnProperty()
、toString()
、valueOf()
等
最后写的 Object constructor
不仅可以创建 "Hash-like" 对象,还可以创建任何其他类型的对象(数组、字符串等)。 javascript 中的全部都是对象,甚至是原始对象(它们有包装对象,并且有自己的构造函数)。
示例:
persons = new Object([person_1, person_2, person_3])
person_age = new Object(18)
person_name = new Object('John')
我们可以将以上所有表达式写成其他语法:
persons = new Array(person_1, person_2, person_3) //or
persons = [person_1, person_2, person_3]
person_age = new Number(18) //or
person_age = 18
person_name = new String('John') //or
person_name = 'John'
无需 new
即可使用适当的全局对象创建字符串和数字
新对象类型
如果需要创建新类型的对象,必须定义新的构造函数并定义原型(ECMAScript 5.1)
NewObjectType = function(arg1, arg2){
this.arg1 = arg1 //define object's property arg1
this.arg2 = arg2 //define object's property arg2
private_function = function(){}
this.public_function = function(){} //this function can't be inherited, because not in prototype
}
NewObjectType.prototype = {
constructor : NewObjectType,
public_inheritable_function_1 : function(){},
public_inheritable_function_2 : function(){}
}
//creating new instance of NewObjectType:
my_new_object = new NewObjectType(arg1, arg2)
my_new_object instanceof NewObjectType //true
my_new_object instanceof Object //true, because prototype was created with {} literal, and Object's prototype built into the prototype chain
解释:
调用 new NewObjectType
时,将创建 NewObjectType 的新实例。 NewObjectType
构造函数的 Prototype
属性 将与新实例的隐藏 __proto__
属性 链接。
没有原型的对象
如果需要创建没有对象方法的清晰对象,则必须使用创建方法创建没有原型的对象:
person = Object.create(null)
作为简单的键值存储可能会有用
类型,不是从对象继承的
如果需要在原型链中创建没有对象原型的新类型对象,可以使用以下语法:
NewObjectType = function(arg1, arg2){}
NewObjectType.prototype = Object.create(null)
NewObjectType.prototype.constructor = NewObjectType
NewObjectType.prototype.public_inheritable_function = function(){}
my_new_object = new NewObjectType(arg1, arg2)
my_new_object instanceof NewObjectType //true
my_new_object instanceof Object //false
我是 JavaScript 的初学者,我发现一个概念非常混乱。考虑以下代码:
var person = {
firstName :"Penelope",
lastName :"Barrymore",
// Since the "this" keyword is used inside the showFullName method below, and the showFullName method is defined on the person object,
// "this" will have the value of the person object because the person object will invoke showFullName ()
showFullName:function () {
console.log (this.firstName + " " + this.lastName);
}
}
person.showFullName (); // Penelope Barrymore
人是 class 还是函数还是只是一个变量?
如果假设那个人是 class,代码 person.showFullName ();
是调用它的正确方法吗,因为在 C# 或我们编写的任何其他语言中
person perObj = new person();
perObj.showFullName();
?
person
是一个对象。它有 3 个属性,名为 firstName
、lastName
和 showFullName
。前两个属性包含字符串。最后一个 属性 包含一个函数。
当您使用语法 <expression>.<function>(<arguments>)
调用函数时,其中 <expression>
求值为一个对象,而 <function>
是其属性之一的名称,那么当函数是 运行 特殊变量 this
被设置为对象。这就是 this.firstName
和 this.lastName
能够访问对象的那些属性的方式。
当只有一个对象时,此功能不是很有用,因为它可以很容易地只使用 person
变量。但是您可以对多个对象使用相同的函数。
function showFull() {
console.log(this.firstName + " " + this.lastName);
}
var person1 = {
firstName: "Penelope",
lastName: "Barrymore",
showFullName: showFull
};
var person2 = {
firstName: "John",
lastName: "Smith",
showFullName: showFull
}
person1.showFullName(); // Penelope Barrymore
person2.showFullName(); // John Smith
JavaScript 没有 类 或者不是 class-based 语言。相反,我们说它是一种 prototype-based 语言。
补充一下 Barmar,您也可以这样做(以防您发现它更类似于 C#):
var person = function() {
this.firstName = "";
this.lastName = "";
}
person.prototype.showFullName = function () {
console.log (this.firstName + " " + this.lastName);
}
var perObj = new person();
perObj.firstName = "Penelope";
perObj.lastName = "Barrymore";
perObj.showFullName();
它是一个对象,而不是 class。
这样想:
在其他 classical OO 语言中,当您实例化 class 时, 你得到一个实例;这个实例相当于 JavaScript object -
JavaScript 对象是动态的 "bags" 属性。它是一组 name-value 对,这些值可以是任何类型 - 函数或对象本身。
在你的例子中,firstName, lastName, and showFullName
是 person 对象的属性。
您使用点 (.) 表示法访问对象的属性,
例如:person.firstName, person.showFullName()
person
实际上是JavaScript中的一个对象字面量。对象文字是那些被定义为
var obj = {
// Properties and methods
};
并且它们的类型是对象。在 JavaScript 中我们没有任何叫做 class 的东西。
- 一切都是对象。 (偶函数)
An object literal is a comma-separated list of name-value pairs wrapped in curly braces. Object literals encapsulate data, enclosing it in a tidy package.
http://www.dyn-web.com/tutorials/object-literal/
虽然我们在 ECMAScript 6 中确实有 classes,但它们并不像其他语言中那样真实 classes。
MDN 说:
JavaScript classes are introduced in ECMAScript 6 and are syntactical sugar over JavaScript's existing prototype-based inheritance. The class syntax is not introducing a new object-oriented inheritance model to JavaScript. JavaScript classes provide a much simpler and clearer syntax to create objects and deal with inheritance.
Is person a class or function or just a variable?
JavaScript 没有 类。变量 person 是指向保存对象的内存位置的变量。
对象本身有几个方面。有一组附加的属性都附加到 person 对象。其中一个属性包含一个值,它是函数对象。这个函数对象包含一个执行上下文。
Execution ContextECMA 有本地环境、词法环境和 this 绑定。 this 绑定指向 person 对象。函数的局部环境限定为函数内部的声明,函数的词法环境限定为可用于 Person 对象的声明。
person
在您的代码中是一个 object
。也就是说,person
是Object
的实例,person
原型和其他对象中的原型一样,由{}
初始化器创建:
// Object initialiser or literal
person = {
some methods and properties
}
// Called as a constructor
person = new Object({some methods and properties})
这意味着你的person
对象从原型继承对象特定的方法,例如hasOwnProperty()
、toString()
、valueOf()
等
最后写的 Object constructor
不仅可以创建 "Hash-like" 对象,还可以创建任何其他类型的对象(数组、字符串等)。 javascript 中的全部都是对象,甚至是原始对象(它们有包装对象,并且有自己的构造函数)。
示例:
persons = new Object([person_1, person_2, person_3])
person_age = new Object(18)
person_name = new Object('John')
我们可以将以上所有表达式写成其他语法:
persons = new Array(person_1, person_2, person_3) //or
persons = [person_1, person_2, person_3]
person_age = new Number(18) //or
person_age = 18
person_name = new String('John') //or
person_name = 'John'
无需 new
新对象类型
如果需要创建新类型的对象,必须定义新的构造函数并定义原型(ECMAScript 5.1)
NewObjectType = function(arg1, arg2){
this.arg1 = arg1 //define object's property arg1
this.arg2 = arg2 //define object's property arg2
private_function = function(){}
this.public_function = function(){} //this function can't be inherited, because not in prototype
}
NewObjectType.prototype = {
constructor : NewObjectType,
public_inheritable_function_1 : function(){},
public_inheritable_function_2 : function(){}
}
//creating new instance of NewObjectType:
my_new_object = new NewObjectType(arg1, arg2)
my_new_object instanceof NewObjectType //true
my_new_object instanceof Object //true, because prototype was created with {} literal, and Object's prototype built into the prototype chain
解释:
调用 new NewObjectType
时,将创建 NewObjectType 的新实例。 NewObjectType
构造函数的 Prototype
属性 将与新实例的隐藏 __proto__
属性 链接。
没有原型的对象
如果需要创建没有对象方法的清晰对象,则必须使用创建方法创建没有原型的对象:
person = Object.create(null)
作为简单的键值存储可能会有用
类型,不是从对象继承的
如果需要在原型链中创建没有对象原型的新类型对象,可以使用以下语法:
NewObjectType = function(arg1, arg2){}
NewObjectType.prototype = Object.create(null)
NewObjectType.prototype.constructor = NewObjectType
NewObjectType.prototype.public_inheritable_function = function(){}
my_new_object = new NewObjectType(arg1, arg2)
my_new_object instanceof NewObjectType //true
my_new_object instanceof Object //false