详细理解JavaScript:它是一个类、一个函数,还是仅仅是一个变量

Understanding JavaScript in detail: is it a class, a function, or just a variable?

本文关键字:一个 函数 仅仅是 变量 JavaScript      更新时间:2023-09-26

我是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

人是一个类或函数,还是仅仅是一个变量?

如果假设那个人是一个类,那么代码person.showFullName ();是调用它的正确方式吗?因为在C#或任何其他语言中,我们编写

person perObj = new person();
perObj.showFullName();

person是一个对象。它有三个属性,分别命名为firstNamelastNameshowFullName。前两个属性包含字符串。最后一个属性包含一个函数。

当使用语法<expression>.<function>(<arguments>)调用函数时,其中<expression>计算为对象,<function>是其属性之一的名称,则在函数运行时,将特殊变量this设置为对象。这就是this.firstNamethis.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

只需添加到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();

它是一个对象,而不是类。

这样想:

在其他经典OO语言中,当实例化时,您会得到一个实例;这个实例相当于一个JavaScript对象-

JavaScript对象是属性的动态"袋子"。它是一组名称-值对,这些值可以是任何类型——函数或对象本身。

在你的例子中,firstName, lastName, and showFullName是人-物的性质。

使用点(.)表示法访问对象的属性,例如:person.firstName, person.showFullName()

person实际上是JavaScript中的对象文字。对象文字是那些被定义为的文字

var obj = {
    // Properties and methods
};

它们的类型是对象。在JavaScript中,我们没有任何名为的东西。

  • 所有都是一个对象。(偶数函数)

对象文字是一个逗号分隔的名称值对列表,用大括号括起来。对象文字封装数据,将其封装在一个整洁的包中。

http://www.dyn-web.com/tutorials/object-literal/


尽管我们在ECMAScript 6中确实有类,但它们并不像在其他语言中那样是真正的类。

MDN表示:

JavaScript类在ECMAScript 6中引入,在语法上是sugar对JavaScript现有的基于原型的继承。这个类语法是而不是引入了一种新的面向对象继承模型转换为JavaScript。JavaScript类提供了一个简单得多的更清晰的语法来创建对象和处理继承。

人是一个类或函数,还是仅仅是一个变量?

JavaScript没有类。变量person是指向保存对象的内存位置的变量。

对象本身有几个方面。有一组附加的属性,这些属性都附加到person对象上。其中一个属性包含一个作为函数对象的值。此函数对象包含一个执行上下文。

执行上下文ECMA有一个本地环境、一个词法环境和一个this绑定。this绑定指向person对象。函数的本地环境的作用域是函数内部的声明,函数的词法环境的作用范围是Person对象可用的声明。

代码中的personobject。换句话说,personObject的实例,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 的情况下使用适当的全局对象创建

MDN 上的页面

新对象类型

如果需要创建新类型的对象,必须定义新的构造函数并定义原型(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__属性链接。

没有原型的对象

如果需要在没有object方法的情况下创建clear对象,则必须使用create方法在没有原型的情况下进行创建:

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没有类或不是基于类的语言。相反,我们说它是一种基于原型的语言。