从零开始学前端 - 16. JS对象Object介绍及常用方法

    技术2026-03-28  9

    作者: 她不美却常驻我心 博客地址: https://blog.csdn.net/qq_39506551 微信公众号:老王的前端分享 每篇文章纯属个人经验观点,如有错误疏漏欢迎指正。转载请附带作者信息及出处。

    从零开始学前端 - 16. JS对象Object

    一、什么是对象二、对象的方法1. 创建对象2. 访问对象3.对象的增删改查3.1 增加属性3.2 删除属性3.3 修改对象属性3.4 查找对象属性3.5 检查对象中是否存在属性 4. 内置方法4.1 Object.assign() 复制对象的可枚举属性4.2 Object.create() 创建一个新对象4.3 Object.defineProperty() 定义或修改对象属性4.4 Object.defineProperties() 定义或修改对象属性4.5 Object.getOwnPropertyDescriptor()4.6 Object.getOwnPropertyNames()4.7 Object.keys()4.8 Object.hasOwnProperty()4.9 Object.freeze() 三、 getter 和 setter四、 原型及原型链

      对象这一概念是初学者比较难以理解的点,理论性的东西较多,而且需要理解的思想也不少,所以初学者可以先将对象理解成一种特殊的数据存储方式,再慢慢理解。

    一、什么是对象

      对象 Object 是 JS 的一种特殊的基本数据类型。有一句话非常的有名,叫做 万物皆对象 ,也就是说,JS 中的所有事物都是对象,包括字符串、数字等。

    var str = "字符串"; // 实际上创建了一个新的字符串对象,继承了 String 对象的属性和方法。 console.log(str.__proto__); // 指向 String 对象

       对象 Object 可以看做是拥有属性和方法的数据。我们来举个生活中的例子来详细说明什么是对象:

       我们将动物 Animal 看做是一个类,而狗 dog 是属于动物这个类中的一个对象,狗的名字、年龄、性别可以看做是它的属性,而它会跑、会吃东西这些动作行为,可以看做是它的方法。( 类 + 对象 的形式是面向对象编程的基础,初学者可以慢慢理解)

    var dog = { name : "旺财", age : "3", sex : "公", run : function(){ console.log("跑"); }, eat : function(){ console.log("吃"); } };

       我们简单的介绍了一下什么叫做对象,并且通过代码将它的属性和方法描述了出来,对象可以看做是属性方法的集合,通过键值对的方式储存起来,每个键名为这个对象的属性名和方法名。    然而对象并不只是一种数据存储方式,在 JS 中,它是一个极为特殊的存在,因为它除了这些属性外,还从原型对象上继承了一些属性和方法,对象的属性通常都是继承的属性。这种从原型上继承的行为,也是 JS 的核心特征。

      Object同时也是一种复合类型的数据,可以将很多的数据通过键值对的形式表示出来。接下来我们通过对象的方式来对数据进行存储:

    var obj = { author_name : "她不美却常驻我心" , Wechar : "老王的前端分享", "author age" : 18, "标题" : "从零开始学前端" , "if" : "使用关键字命名" }

      键名通常是字符串类型的数据,符合 JS 的命名标准。任何的字符都可以通过增加引号来作为对象的键名,但我们并不推荐使用中文字符、保留关键字等不符合命名规范的特殊的方式进行命名,比如说例子中的"键名"、"if"。   符合命名规范的字符可以直接作为对象的键名,不需要添加额外的引号,而对象的值可以是任意数据类型。

    二、对象的方法

    1. 创建对象

    直接创建 var obj = {}; 通过构造函数创建 var obj = new Object(); // 等同于 var obj = {}; 通过对象方法创建 var obj = Object.create();

    2. 访问对象

    var obj = { a : 1, "特殊键名" : 2 } 对象名 + “.” + 属性名 (ObjectName.propertyName) obj.a; // 1 obj.特殊键名 // 2 特殊键名采用这种方式访问在低版本浏览器中会报错 对象名 + " [ " + " 特殊属性名" + " ] " (ObjectName[“propertyName”]; obj["a"]; // 1 obj["特殊键名"]; // 2

      一般我们采用第一种方式来访问对象的属性,当属性名为中文等特殊情况时,可以使用第二种方式来访问。

    3.对象的增删改查

    3.1 增加属性

    var obj = {}; obj.a = 1; // 为 Object 添加新方法 Object.prototype.addObject = function (key, value) { this[key] = value; return this; } obj.addObject("test",3); // {a : 1, test : 2}

    3.2 删除属性

    var obj = { a : 1 }; delete obj.a;

    3.3 修改对象属性

    var obj = { a : 1 }; obj.a = 2 ; // 重新定义已经拥有的方法 Object.prototype.create = function(){ // do something }

    3.4 查找对象属性

    var obj = { a : 1, "特殊键名" : 2 } 使用循环遍历对象: for (var key in obj) { console.log(key); // a , 特殊键名 console.log(obj[key]) // 1 , 2 } // 按照对象属性的顺序依次打印。 使用对象内置方法:Object.keys() var keys = Object.keys(obj); console.log(keys); ["a" , "特殊键名"]; // 返回一个包括对象内可枚举属性以及方法名称的数组 使用对象内置方法:Object.getOwnPropertyNames() var keys = Object.getOwnPropertyNames(testObj); console.log(keys); // 返回一个指定对象所有自身属性的属性名的数组

    3.5 检查对象中是否存在属性

    使用运算符 in 如果对象的属性或者继承属性中 var obj = { a : 1 }; "a" in obj; // true "b" in obj; // false "valueOf" in obj // true obj 继承了 Object 对象原型链上的方法。 使用内置方法 Object.hasOwnProperty() obj.hasOwnProperty("a"); // true obj.hasOwnProperty("valueOf"); // false 使用内置方法 Object.propertyIsEnumerable obj.propertyIsEnumerable("a"); // true obj.propertyIsEnumerable("valueOf"); // false

    4. 内置方法

    4.1 Object.assign() 复制对象的可枚举属性

      语法:Object.assign(target, source...)   作用:将对象的可枚举属复制到目标对象,并返回目标对象。   实例:

    var obj1 = {}; var obj2 = { a: 1, b: 2 }; var obj3 = { a: 2, c: 3 }; var newObj = Object.assign(obj1, obj2,obj3); console.log(obj1); // {a: 2, b: 2, c: 3} console.log(obj2); // {a: 1, b: 2} console.log(obj3); // {a: 2, c: 3} console.log(newObj); // {a: 2, b: 2, c: 3} 如果目标对象中具有相同的属性名称,则后面的源对象的属性将类似地覆盖前面的源对象的属性;该方法实现的是浅拷贝,继承属性和不可枚举属性是不能复制的;

    4.2 Object.create() 创建一个新对象

      语法:Object.create(proto, {property})   作用:创建一个新对象,使用现有的对象来提供新创建的对象的原型。   实例:

    var obj = Object.create(Object.prototype, { a: { writable: false, // 设置值是否可更改 configurable: true, // 设置属性是否可配置 enumerable: true, // 设置属性是否可枚举 value: 1 // 值 }, b:{ } }) obj.a = 2; console.log(obj); // { a : 1}

    4.3 Object.defineProperty() 定义或修改对象属性

      语法:Object.defineProperty(obj, key, descriptor)   作用:在一个对象上定义新的属性或修改现有属性,并返回该对象。   实例:

    var obj = { a : 1 }; Object.defineProperty(obj, 'b',{ configurable : true , enumerable : true , writable: true , get: function(){}, set: function(){}, value : 2 })

    4.4 Object.defineProperties() 定义或修改对象属性

      语法:Object.defineProperties(obj, props)   作用:在一个对象上定义新的属性或修改现有属性,并返回该对象。   实例:

    var obj = { a: 1 }; Object.defineProperties(obj, { a: { value: 2, writable: false }, b: { value: 3, writable: true } }); obj.a = 4 ; obj.b = 5 ; console.log(obj); // { a : 2 , b : 5 }

    4.5 Object.getOwnPropertyDescriptor()

      语法:Object.getOwnPropertyDescriptor(obj, key)   作用:返回对象中属性对应的属性描述。   实例:

    var obj = { a: 1 }; var desc = Object.getOwnPropertyDescriptor(obj, "a"); console.log(desc); // {value: 1, writable: true, enumerable: true, configurable: true}

    4.6 Object.getOwnPropertyNames()

      语法:Object.getOwnPropertyNames(obj)   作用:返回一个包含对象中所有属性的数组。   实例:

    var obj = Object.create(Object, { a: { value: 1, enumerable: false }, b: { value: 2, enumerable: true } }) var keys = Object.getOwnPropertyNames(obj); console.log(keys); // ["a", "b"]

    4.7 Object.keys()

      语法:Object.keys(obj)   作用:返回一个包含对象中所有可枚举属性的数组。   实例:

    var obj = Object.create(Object, { a: { value: 1, enumerable: false }, b: { value: 2, enumerable: true } }) var keys = Object.keys(obj); console.log(keys); // ["b"]

    4.8 Object.hasOwnProperty()

      语法:Object.hasOwnProperty(key)   作用:检测对象中是否含有指定属性。   实例:

    var obj = { a : 1 } obj.hasOwnProperty("a"); // true obj.hasOwnProperty("b"); // false

    4.9 Object.freeze()

      语法:Object.freeze(obj)   作用:不允许对对象进行任何修改。   实例:

    var obj = { a : 1 } Object.freeze(obj);

    更多关于 Object 的方法及属性,请 点击这里查看。

    三、 getter 和 setter

      对象的每一个属性都可以看成是由键值对构成的,我们可以使用 getter 和 setter 方法来代替属性值。通过这种方法定义的属性被称为 存取器属性。

    var obj = { _hour_: 0, get hour() { return "现在是" + this._hour_ + "点"; }, set hour(h) { this._hour_ = h < 10 ? '0' + h : '' + h; } } obj.hour = 22; console.log(obj.hour); // 现在是22点 obj.hour = 9; console.log(obj.hour); // 现在是09点

      当我们访问对象的属性时,会调用 getter 方法,给属性赋值时,会调用 setter 方法。   使用 getter 和 setter 可以在对象的赋值和读取前做一些预处理的工作,比如上方代码在读取和设置时间时对其进行了一些预处理,保证在使用时不需要在进行额外的处理。

      当一个属性只存在 getter 方法时,这个属性就是只读属性,不允许对它的值进行修改;如果只存在 setter方法,则被称为只写属性,读取属性时会返回 undefined ;

    四、 原型及原型链

      JS 本身并不具有 “类” 的概念,所有的一切都是对象。对象与对象之间的关系是如何联系起来的呢?就是靠着原型链串联在一起的。   每一个对象都具有一个 __proto__ 属性,它指向的就是这个对象所继承的原型。而原型也拥有一个 prototype 属性与之相对应,也就是说:当前对象的 __proto__ 属性与它继承的原型对象的 prototype 相同。

    var str1 = "字符串"; console.log(str1); console.log(str1.__proto__); var str2 = new String("字符串"); console.log(str2); console.log(str2.__proto__); console.log(str1.__proto__ === String.prototype);

      可以发现,我们通过直接赋值的方式创建的是一个普通的字符串类型的数据,而通过构造函数创建的则是一个对象类型的字符串数据,但他们的原型都指向了 String 对象。也就是说,他们都是从 String 这个 “父类” 下的 “子类” ,继承了父类的方法。   接下来我们在打印一下 String 的原型和 Object 的原型:

    console.log(str1.__proto__.__proto__); console.log(Object.prototype); console.log(str1.__proto__.__proto__ === Object.prototype);

      这样的结果已经很明显了,我们声明的普通字符串继承自 String 对象,而 Striing 对象又继承了 Object 对象。这里的指向继承关系,我们就可以将其看做是 JS 的原型链。

      JS 的一切都是基于对象进行的设计,要说的内容也太多了点,洋洋洒洒写了半天感觉连个大概也没说明白,内置方法更是一带而过,原型和原型链也只是说了个大概,还有对象的继承等等根本就没有提。这里先立个 flag ,等写完函数的相关内容之后,再来重新写一下对象。(如果没实现的话,我就返回来把这段话删掉。笑)


    种一棵树,最好的时间是十年前,其次是现在。人的一生,总的来说就是不断学习的一生。 蚕吐丝,蜂酿蜜。人不学,不如物。与其纠结学不学,学了有没有用,不如学了再说。


    每篇文章纯属个人经验观点,如有错误疏漏欢迎指正。转载请附带作者信息及出处。您的评论和关注是我更新的动力! 请大家关注我的微信公众号,我会定期更新前端的相关技术文章,欢迎大家前来讨论学习。 都看到这里了,三连一下呗~~~。点个收藏,少个 Bug 。

    Processed: 0.011, SQL: 9