📜  Javascript 中的对象

📅  最后修改于: 2022-05-13 01:56:26.569000             🧑  作者: Mango

Javascript 中的对象

在 JavaScript 中,对象是最重要的数据类型,它构成了现代 JavaScript 的构建块。这些对象与 JavaScript 的原始数据类型(数字、字符串、布尔值、null、未定义和符号)完全不同,因为这些原始数据类型都存储一个值(取决于它们的类型)。

  • 对象更复杂,每个对象可能包含这些原始数据类型以及引用数据类型的任意组合。
  • 对象,是一种引用数据类型。分配了引用值的变量将获得一个引用或指向该值的指针。该引用或指针指向内存中存储对象的位置。变量实际上并不存储值。
  • 粗略地说, JavaScript 中的对象可以定义为相关数据、原始类型或引用类型的无序集合,以“键:值”对的形式。这些键可以是变量或函数,在对象的上下文中分别称为属性和方法。

可以使用带有可选属性列表的图形括号 {…} 创建对象。属性是“键:值”对,其中键是字符串(也称为“属性名称”),值可以是任何东西。
为了理解这个相当抽象的定义,让我们看一个 JavaScript 对象的例子:

let school = {
    name : "Vivekananda School",
    location : "Delhi",
    established : "1971"
}

在上面的例子中,“name”、“location”、“established”都是“keys”“Vivekananda School”、“Delhi”和1971分别是这些keys的值。

这些键中的每一个都称为对象的属性。 JavaScript 中的对象也可以有一个函数作为成员,在这种情况下,它被称为该对象的方法

让我们看一个这样的例子:

// javascript code demonstrating a simple object
let school = {
    name: 'Vivekananda School',
    location : 'Delhi',
    established : '1971',
    displayInfo : function(){
        console.log(`${school.name} was established 
              in ${school.established} at ${school.location}`);
    }
}
school.displayInfo();   

输出:

在上面的示例中, “displayinfo”是学校对象的一种方法,用于处理对象的数据,存储在其属性中。

JavaScript 对象的属性

属性名称可以是字符串或数字。如果属性名称是数字,则必须使用“括号表示法”访问它们,如下所示:

let school = {
    name: 'Vivekananda School',
    location : 'Delhi',
    established : '1971',
    20 : 1000,
    displayInfo : function(){
        console.log(`The value of the key 20 is ${school['20']}`);
    }
}
school.displayInfo();   

输出:

但稍后会详细介绍括号符号。

属性名称也可以是包含多个空格分隔的单词的字符串。在这种情况下,这些属性名称必须用引号引起来:

let school = {
    "school name" : "Vivekananda School",
}

与作为数字的属性名称一样,它们也必须使用括号表示法来访问。就像我们想从“Vivekananda School”访问“Vivekananda”一样,我们可以这样做:

// bracket notation 
let school = {
    name: 'Vivekananda School',
    displayInfo : function(){
        console.log(`${school.name.split(' ')[0]}`);
    }
}
school.displayInfo(); // Vivekananda

输出:

在上面的代码中,我们使用了括号表示法以及 javascript 提供的 split 方法,您将在字符串文章中了解这些方法。

继承的属性

对象的继承属性是从对象的原型继承的那些属性,而不是为对象本身定义的属性,这被称为对象的 Own 属性。要验证一个属性是否是对象的 Own 属性,我们可以使用hasOwnProperty方法。

属性属性
JavaScript 中的数据属性有四个属性。

  • value:属性的值。
  • writable:当为true时,属性的值可以改变
  • enumerable:当为真时,该属性可以通过“for-in”枚举进行迭代。否则,该属性被称为不可枚举的。
  • 可配置:如果为 false,尝试删除属性、将属性更改为访问或属性或更改其属性(除了 [[Value]] 或将 [[Writable]] 更改为 false)将失败。
// hasOwnProperty code in js
const object1 = new Object();
object1.property1 = 42;
  
console.log(object1.hasOwnProperty('property1')); // true

输出:

创建对象

有几种方法或语法可以创建对象。我们已经使用过其中之一,称为 Object字面量量语法。除了对象字面量量语法之外,JavaScript 中的对象也可以使用构造函数、对象构造函数或原型模式来创建。

  1. 使用对象字面量语法:对象字面量语法使用 {…} 符号直接初始化对象及其方法/属性。
    让我们看一个使用此方法创建对象的示例:
    var obj = {
        member1 : value1,
        member2 : value2,
    };
    

    这些成员可以是任何东西——字符串、数字、函数、数组甚至其他对象。像这样的对象被称为对象字面量量。这与其他涉及使用构造函数和类或原型的对象创建方法不同,这些方法已在下面讨论。

  2. 对象构造器:在 JavaScript 中创建对象的另一种方法是使用“对象”构造器。 Object 构造函数为给定值创建一个对象包装器。这与“new”关键字结合使用允许我们初始化新对象。
    例子 :
    const school = new Object();
    school.name = 'Vivekanada school';
    school.location = 'Delhi';
    school.established = 1971;
      
    school.displayInfo = function(){
        console.log(`${school.name} was established 
              in ${school.established} at ${school.location}`);
    }
      
    school.displayInfo();
    

    输出:

    上面提到的两种方法不太适合需要创建多个同类对象的程序,因为它需要为每个这样的对象重复编写上述代码行。为了解决这个问题,我们可以利用 JavaScript 中另外两种创建对象的方法来显着减轻这种负担,如下所述:

  3. 构造函数: JavaScript 中的构造函数与大多数其他 OOP 语言一样,为创建对象提供了模板。换句话说,它定义了一组属性和方法,这些属性和方法对于使用构造函数初始化的所有对象都是通用的。
    让我们看一个例子:
    function Vehicle(name, maker) {
       this.name = name;
       this.maker = maker;
    }
      
    let car1 = new Vehicle('Fiesta', 'Ford');
    let car2 = new Vehicle('Santa Fe', 'Hyundai')
      
    console.log(car1.name);    // Output: Fiesta
    console.log(car2.name);    // Output: Santa Fe
    

    输出:

    注意函数Vehicle 之前“new”关键字的使用。在任何函数将其转换为构造函数之前,以这种方式使用“new”关键字。 “new Vehicle()”实际上做的是:

    • 它创建一个新对象并将该对象的构造函数属性设置为学校(需要注意的是,此属性是一个特殊的默认属性,不可枚举,不能通过手动设置“constructor: someFunction”属性来更改)。
    • 然后,它将对象设置为与Vehicle函数的原型对象一起工作(JavaScript 中的每个函数都获取一个原型对象,该原型对象最初只是一个空对象,但可以修改。该对象在实例化时从其构造函数的原型对象继承所有属性)。
    • 然后在新对象的上下文中调用Vehicle(),也就是说在构造函数(vehicle())中遇到“this”关键字时,指的是第一步创建的新对象。
    • 完成后,新创建的对象将返回给 car1 和 car2(在上面的示例中)。

    在类内部,可以有名为constructor()的特殊方法。

    class people {
        constructor()
        {
            this.name = "Adam";
        }
    }
      
    let person1 = new people();
      
    // Output : Adam    
    console.log(person1.name);    
    

    输出:

    在一个类中具有多个名为constructor()的函数会导致错误。

  4. 原型:创建对象的另一种方法是使用原型。每个 JavaScript函数默认都有一个prototype对象属性(默认为空)。方法或属性可以附加到此属性。原型的详细描述超出了对象介绍的范围。
    但是,您可能会熟悉以下使用的基本语法:
    let obj = Object.create(prototype_object, propertiesObject)
              // the second propertiesObject argument is optional
    

    使用 Object.create() 方法的一个例子是:

    let footballers = {
        position: "Striker"
    }
       
    let footballer1 = Object.create(footballers);
       
        // Output : Striker    
    console.log(footballer1.position); 
    

    输出:

    在上面的示例中,足球运动员用作创建对象“footballer1”的原型。

    以这种方式创建的所有对象都从其原型对象继承所有属性和方法。原型可以有原型,那些可以有原型等等。这在 JavaScript 中称为原型链。该链以Object.prototype终止,它是所有对象的默认原型回退。默认情况下,Javascript 对象从 Object.prototype 继承属性和方法,但这些可能很容易被覆盖。值得注意的是,默认原型并不总是 Object.prototype。例如,字符串和数组有自己的默认原型——分别是 String.prototype 和 Array.prototype。

访问对象成员

可以使用以下方式访问对象成员(属性或方法):

  1. 点符号:
    (objectName.memberName)
    let school = {
        name : "Vivekanada",
        location : "Delhi",
        established : 1971,
        20 : 1000,
        displayinfo : function() {
            console.log(`${school.name} was established 
              in ${school.established} at ${school.location}`);
        }
      
    }
      
    console.log(school.name);
      
    console.log(school.established);
    

    输出:

  2. 括号符号:
    objectName["memberName"]
    let school = {
        name : "Vivekanada School",
        location : "Delhi",
        established : 1995,
        20 : 1000,
        displayinfo : function() {
            document.write(`${school.name} was established 
              in ${school.established} at ${school.location}`);
        }
    }
      
    // Output : Vivekanada School
    console.log(school['name']); 
      
    // Output: 1000
    console.log(school['20']); 
    

    输出:

与点表示法不同,括号关键字适用于任何字符串组合,包括但不限于多字字符串。
例如:

somePerson.first name // invalid
    somePerson["first name"] // valid

与点表示法不同,方括号表示法还可以包含名称,这些名称是任何表达式变量的结果,其值是在运行时计算的。
例如 :

let key = "first name" somePerson[key] = "Name Surname"

使用点符号时无法进行类似的操作。

遍历对象的所有键

要遍历对象的所有现有可枚举键,我们可以使用for...in构造。值得注意的是,这允许我们仅访问对象的可枚举属性(回想一下,可枚举是数据属性的四个属性之一)。
例如,从 Object.prototype 继承的属性是不可枚举的。但是,从某个地方继承的可枚举属性也可以使用for...in构造来访问
例子:

let person = {
    gender : "male"
}
  
var person1 = Object.create(person);
person1.name = "Adam";
person1.age = 45;
person1.nationality = "Australian";
  
for (let key in person1) {
// Output : name, age, nationality 
// and gender
    console.log(key); 
}          

输出:

删除属性

要删除对象的属性,我们可以使用delete运算符。下面列出了它的使用示例:

let obj1 = {
    propfirst : "Name"
} 
  
// Output : Name
console.log(obj1.propfirst); 
delete obj1.propfirst
  
// Output : undefined
console.log(obj1.propfirst);             

输出:

需要注意的是,我们不能以这种方式删除继承的属性或不可配置的属性。
例如 :

let obj1 = {
    propfirst : "Name"
} 
// Output : Name
console.log(obj1.propfirst) 
  let obj2 = Object.create(obj1);
  
 // Output : Name
  console.log(obj2.propfirst);
    
  // Output : true.
  console.log(delete obj2.propfirst); 
  
    // Surprisingly Note that this will return true
    // regardless of whether the deletion was successful
  
    // Output : Name    
    console.log(obj2.propfirst); 

输出: