专栏首页Super 前端JavaScript对象

JavaScript对象

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://ligang.blog.csdn.net/article/details/42590565

一、对象

1. 对象是一种复合值:它将很多值聚合在一起,可以通过名字访问这些值。对象也可以看做是属性的无序集合,每个属性都是一个名/值对。属性名是字符串,因此我们可以把对象看成是从字符串到值的映射。 2. 除了字符串、数字、true、false、null和undefined之外,JavaScript中的值都是对象。 3. 对象时可变的,问题通过引用而非值来操作对象。

二、对象特性和属性特性

每个对象拥有三个相关的对象特性: 1. 对象的原型(prototype)指向另外一个对象,本对象的属性继承自它的原型对象; 2. 对象的类(class)是一个标识对象类型的字符串; 3. 对象的扩展标记(extensible flag)指明了是否可以向该对象添加新属性。 属性特性: 1. 可写(writable attribute),表明是否可以设置该属性的值; 2. 可枚举(enumerable attribute),表明是否可以通过for/in循环返回该属性; 3. 可配置(configurable attribute),表明是否可以删除或修改该属性。

三、创建对象

可以通过对象直接量、关键字new和(ECMAScript 5中的)Object.create()函数来创建对象。 1. 对象直接量

var book = {
	'main title':"javascript",			//属性名字里有空格,必须用字符串表示
	'sub-title':'The Definitive Guide',	//属性名字里有连字符,必须用字符串表示
	'for':'all audiences',				//属性名字是保留字,必须用字符串表示
	author:{
		firstname:'lee',
		surname:'gang'
	}
};

如果在一个重复调用的函数中的循环体内使用了对象直接量,它将创建很多新对象,并且每次创建的新对象的属性值也有可能不同。 2. 通过new创建对象

var obj = new Object(); 	//创建一个空对象,和{}一样

3. Object.create()

var obj = Object.create({x:1,y:2});		//obj继承了属性x和y

其创建一个对象,其中第一个参数是这个对象的原型;第二个可选参数,用以对对象的属性进行进一步描述

四、原型

1. 没有原型的对象为数不多,Object.prototype就是其中之一。它不继承任何属性。 2. new Date() 创建的Date对象的属性继承自Date.prototype,Date.prototype的属性继承自Object.prototype。这一系列链接的原型对象就是所谓的“原型链”。 3. 通过原型继承创建一个新对象:

function inherit(p){
	if(p == null) throw TypeError();
	if(Object.create)
		return Object.create(p);
	var t = typeof p;
	if(t !== "object" && t !== "function") throw TypeError();
	function(){};
	f.prototype = p;
	return new f();
}

五、属性的查询和设置

[]运算符,它使用字符串值(字符串值是动态的,可以在运行时更改) .运算符,它使用标识符(标识符是静态的,必须写死在程序中)

var a = {x:1,y:2};
for(item in a){
	a.item = 3;
}
// 结果:a.x = 1	a.y = 2

var a = {x:1,y:2};
for(item in a){
	a[item] = 3;
}
// 结果:a.x = 3	a.y = 3

属性赋值操作首先检查原型链,以此判断是否允许赋值操作。如果允许属性赋值操作,它也总是在原始对象上创建属性或对已有的属性赋值,而不会去修改原型链。在JavaScript中,只有在查询属性是才会体会到继承的存在,而设置属性则和继承无关。

// 一种更简练的常用方法,获取sub-title的length
var len = book && book.sub-title && book.sub-title.length;

六、删除属性

delete只是断开属性和宿主对象的联系,而不会去操作属性中的属性。 delete运算符只能删除自有属性,不能删除继承属性(要删除继承属性必须从定义这个属性的原型对象上删除它,而且这会影响到所有继承自这个原型的对象)

a = {p:{x:1}}; 
b = a.p;
delete p;
console.log(b.a);	//仍然是1

所以在销毁对象的时候,要遍历属性中的属性,一次删除。

a = {p:{x:1}};
delete a.p.x;
delete a.p;

某些内置对象是不可配置的,比如通过变量声明和函数声明创建的全局对象的属性:

delete Object.prototype;
var x = 1;
delete this.x;
function f(){}
delete this.f;
上述三种情况均不能被删除

七、检测属性

Javascript对象可以看做属性的集合。 1. in运算符,如果对象的自有属性或继承属性中包含这个属性则返回true。 2. hasOwnPrototype()方法,用来检测给定的名字是否是对象的自有属性。 3. propertyIsEnumerable(),只有检测到是自有属性且这个属性的可枚举性为true才返回true。

null == undefined	//true
null === undefined	//false

八、可枚举属性

for-in循环可以在循环体中遍历对象中所有可枚举的属性(包括自身属性和继承属性) 对象.propertyIsEnumerable("属性") //检测是否可枚举

九、属性特性

1. 由getter和setter定义的属性称做“存取器属性”,其不同于“数据属性”,数据属性只有一个简单的值。 2. 存储器属性4个特性分别是:读取(get)、写入(set)、可枚举性(enumerable)和可配置性(configurable)。 3. 数据属性的4个特性分别是:值(value)、可写性(writable)、可枚举性(enumerable)和可配置性(configurable)。 4. Object.getOwnPropertyDescriptor()只能得到自有属性的描述符,要想获得继承属性的特性,需要遍历原型链,获取原型的方法Object.getPrototypeOf()。

设置属性的特性(不能修改继承属性):
var o = {};
Object.defineProperty(o,"x",{value:1,
			     writable:true,
			     enumerable:false,
			     configurable:true});

十、对象的三个属性

1. 原型属性 Object.getPrototypeOf()可以查询它的原型;检查一个对象是否是另一个对象的原型,可使用isPrototypeOf()。 Mozilla实现的JavaScript对外暴漏了一个专门命名为__proto_的属性,用以直接查询/设置对象的原型。 2. 类属性 默认的toString()方法,返回[object class],然后提取第8个到倒数第二个位置之间的字符。但是大部分对象会重写toString()方法,所以建议使用Object.prototype.toString().call() 3. 可扩展性 Object.isExtensible()判断对象是否可扩展,Object.preventExtensions()转换为不可扩展的。 一旦将对象转换为不可扩展的,将无法再将其转换回可扩展的了。 需要注意,Object.preventExtensions()只影响到对象本身的可扩展性,如果给一个不可扩展的对象的原型添加属性,这个不可扩展的对象同样会继承这些新属性;至此提供了一种从“可扩展”->“不可扩展”之后的思路!! Object.preventExtensions()[不可扩展] -> Object.seal()[不可扩展、自有属性不可配置] -> Object.freeze()[不可扩展、自有属性不可配置、数据属性设置为只读]

十一、对象序列化

对象序列化(serialization)是指将对象的状态转换为字符串,也可将字符串还原为对象。 JSON.stringify()[只能序列化可枚举自有属性]和JSON.parse()

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 或许是你应该了解的一些 ASP.NET Core Web API 使用小技巧

      在目前的软件开发的潮流中,不管是前后端分离还是服务化改造,后端更多的是通过构建 API 接口服务从而为 web、app、desktop 等各种客户端提供业务...

    梁规晓
  • javascript中常用的设计模式,教你写出更好的前端代码

    今天给大家介绍js中常用的设计模式,也让自己对js设计模式有一个更清晰的认识,下面我们直接进入今日的主题

    前端老鸟
  • Spring5.0源码深度解析之SpringBean的生命周期终结

    那么这个MemberServiceImpl对象是交给spring到底是通过反射还是其它方式初始化的?

    须臾之余
  • Spring5.0源码深度解析之SpringBean的生命周期

    说明单例默认是在容器被加载的时候初始化,多例是在每次获取Bean对象的时候初始化。

    须臾之余
  • 源码分析——Android Handler是如何实现线程间通信的

    Handler 作为 Android 消息通信的基础,它的使用是每一个开发者都必须掌握的。开发者从一开始就被告知必须在主线程中进行UI操作。但 Handler ...

    阳仔
  • Lamda 表达式作用域和内置函数式接口

    但是和匿名对象不同的是,这里的变量 num 可以不用声明为 final,该代码同样正确:

    happyJared
  • Android WebView 安全问题汇总

    在使用WebView开发时注入JS对象,当App具有读写SDCARD权限,那么注入的JS对象就可以通过反射机制获取到Java对象Runtime,并调用静态方法来...

    阳仔
  • java小工具-使用springboot-starter启动检查配置是否满足要求

    随着项目不断的迭代,不断的有新的组件加入进来,比如现在项目中就集成了cat,apollo,prometheus,docker,k8s等等 , 随之而来的有一大堆...

    微笑的小小刀
  • ES6数组操作方法

    concat() 方法用于连接两个或多个数组。该方法不会改变现有的数组,仅会返回被连接数组的一个副本。

    用户1437675
  • 用过了那么多开发者工具,这个才真正好用,AI辅助编程,释放你的双手!

    我们平时写代码的时候,多少都会依赖编辑器的代码补全功能,敲几个字母就能补全一个词。可是这么多年过去了,语言升级了很多次,而代码提示却没有升级,还是只能限定在一个...

    江南一点雨

扫码关注云+社区

领取腾讯云代金券