频道栏目
首页 > 程序开发 > web前端 > HTML/CSS > 正文
js对象类型
2018-10-23 13:53:52           
收藏   我要投稿

js对象类型

文章目录

对象简介对象属性详解对象的保护严格模式

对象简介

对象的概念:一组"键值对"(key-value)的集合,无序的数据集合.(键值对是指"键名:键值"这种一对对的形式,其中键名(又称属性,成员)要遵守一定的命名和书写规则;键值可以是js的任何一种数据类型,这包括原始值primitive如number,string,boolean等,也包括一般对象object,函数Function,数组Array)
[说明:键名/键值,属性名/属性值,成员/成员值都是指的同一个东西].

键名/键值:形式结构上的描述 属性名/属性值:css中的概念 成员/成员值:java中的概念

键名/属性名的规则:

对象的属性名都是字符串(ES6引入Symbol值也可作为键名) 不是字符串的,自动转为字符串 如果属性名不符合标识符条件(例如:包含空格),必须加上引号,否则会报错
注:js标识符命名规则 js中标识符可以由 字母、数字、下划线、$ 组成,但不能是保留字; js中标识符只能由 字母、下划线、$ 开始,而不能由数字开始; js中标识符区分大小写

对象的属性(property):(详细内容,参照后面的章节)

各个属性(键值对)之间用逗号","隔开,最后一项的逗号可加也可不加 属性分类:数据属性(data property),访问器属性(accessor property),内部属性(internal property) 各个属性又有各自的特性(attribute)与属性描述符对象(property descriptor)

函数的参数的传递方式:原始类型按值传递,复合类型按引用传递(对象的引用:该对象所在的内存地址,即"指向对象的指针")

属性的操作:

属性的读取与赋值:

点号".":obj.属性名(注意:数字键名不能用此种方法,点号会被当成小数点) 方括号"[]":obj[‘属性名’],方括号内的两个单引号不能省略.并且方括号之内还可以进行字符串处理.例:obj[‘on’+‘click’]

属性(名)查看:Object.keys(obj)方法(不能查看属性值,只能查看含有哪些属性)

删除对象本身的属性:delete命令

格式:delete obj.属性名; 删除成功返回true;该属性不得删除,返回false.(见后续章节) delete命令不能删除继承属性/原型属性

验证属性存在性:in 运算符

格式:‘字符串’ in obj; 检查对象的键名而不是键值 不区分本身属性与继承属性

判断属性是否为本身属性:obj.hasOwnProperty(‘字符串’);

遍历可enumerable的属性:for…in循环
格式:for (var i in obj) {…}

操作同一对象的多个属性:with语句
with(obj) {a=1;b=2;}等同于obj.a=1;obj.b=2;
[注意:with语句操作的必须是对象已经拥有的属性.否则就会创建一个仅在with语句的作用域内有效的新属性.with语句结束后,该属性又变成undefined.正因为如此,我们不推荐使用with语句]

对象属性详解

属性分类:

数据属性(data property):一般的键值对 访问器属性(accessor property):不保存值,但可对访问和赋值操作的实际过程进行自定义 内部属性(internal property):一般无法直接访问,需要借助相应的函数

数据属性(data property):

就是我们说的一般的属性,它保存一个值,要么是数据本身(原始类型),要么是数据的引用(对象). 数据属性的访问与赋值操作的实际过程是默认的,无法修改 数据属性的特性(property attributes):

属性(property)与特性(attribute)是两个不同的概念

属性的特性(attribute)是对属性本身能够进行的行为的约束

数据属性的特性有如下几种:

\

属性特性不能直接进行修改,必须使用专门的方法Object.defineProperty(obj,‘属性名’,属性描述符对象)

注:属性描述符,或者说属性描述符对象是指将要修改的特性与修改值,以键值对的形式书写,并用对象封装.例如{configurable:false,writable:false;}

与属性描述符相关的函数:

Object.defineProperty(obj, ‘属性名’, 属性描述符) Object.defineProperties(obj, 属性-描述符键值对对象)
这里的 属性-描述符键值对对象 是指如下形式的封装对象:
{属性名1:描述符对象1 , 属性名2:描述符对象2,…} Object.create(proto, 属性-描述符键值对对象) Object.getOwnPropertyDescriptor(obj, 属性名):返回特定属性的属性描述符对象;如果不存在该属性,返回undefined.

访问器属性(accessor property):

访问器属性不包含数据值,他们有一对儿getter和setter函数(这两个函数不是必须的,保存在其属性特性Set和Get中)。允许用户在赋值或取值都经过预先设定的函数,从而实现内部属性的那一种特殊效果.

读取访问器属性时,会调用getter函数,这个函数负责返回有效的值。 在写入访问器属性时,会调用setter函数,这个函数负责决定如何处理数据。

属性特性:(前两个与数据属性相同,后两个不同)
\
小结:因为不保存值,所以没有Value和Writable特性,Set和Get取而代之.

访问器属性的修改:不能直接修改,需要用到特定函数Object.defineProperty(obj,‘属性名’,属性描述符对象)或者Object.defineProperties(obj, 属性-描述符键值对对象)

内部属性(internal property):

一些属性仅仅在规范之中用到,它们被称为"内部属性"是因为它们不能通过js直接访问,但也确确实实影响着代码.内部属性的书写都是包含在双方括号([[]])之中的. 所有对象共有的内部属性:
\
\
更多相关资料,请参考:ECMA5.1

重要的内部属性详解:

[[prototype]]:存放当前对象的原型对象的引用
1.函数与函数的原型对象(prototype object):

JavaScript中,创建一个函数A(就是声明一个函数), 浏览器就会在内存中创建一个对象B,而且该函数默认会有一属性 prototype 指向这个对象(即:prototype属性的值) 这个对象B就是函数A的原型对象,简称函数的原型。这个原型对象B也默认会有一个属性 constructor 指向了这个函数A (即:constructor属性的值是函数A) 凡是以函数A为构造函数而创建的对象C,D,E等等,也都有一个内部的[[prototype]]属性,也指向这个对象B.

2.要点一:构造函数的prototype的属性与其实例对象的[[prototype]]属性的区别.
前面的内容提到"内部属性"是不能直接访问到的,需要借助某些函数.而构造函数的prototype属性不是内部属性,而是普通属性;但是其实例对象的[[prototype]]确是内部属性,直接obj.prototype总是返回undefined.
代码:
function Test() {}
var t1 = new Test();
console.log(Test.prototype);
console.log(t1.prototype);
运行结果:
\
3.要点二:任何对象都有构造函数,都有原型对象
对象可以分为字面量对象,new出来的对象和函数对象.显然,new出来的对象都是有构造函数和原型对象的.

字面量对象
代码:

var square = {length: 10};
var pro=Object.getPrototypeOf(square);
console.log(pro);
console.log(pro==Object.prototype);

运行结果:
\
因此,字面量对象的原型是Object.prototype,其构造函数为Object().

函数对象:
代码:

function Test(){}
var proF=Object.getPrototypeOf(Test);
console.log(proF);
console.log(proF==Function.prototype);

运行结果:
\
因此,函数对象的原型是Function.prototype,构造函数为Function().
至此,我们可以得出开头的结论.

4.要点三:任何函数都可以作为构造函数,但不一定都能对其实例对象初始化.
例子1:
代码:

function Test2(x,y){
length=x;
name=y;
}
var T2 = new Test2(1,‘peter’);
console.log(Object.getPrototypeOf(T2)==Test2.prototype);
console.log(T2.length);

运行结果:
\

例子2:
代码:

function Test3(x,y){
this.length=x;
this.name=y;
}
var T3 = new Test3(1,‘peter’);
console.log(Object.getPrototypeOf(T3)==Test3.prototype);
console.log(T3.length);

运行结果:
\
5.我们约定,凡是构造函数,其函数名首字母必须大写.

进一步探讨内部属性
由上面的要点一,我们可以看出,prototype属性像是构造函数的私有属性(类似java的私有成员).构造函数自身可以直接访问,但其实例对象不能直接访问,需要借助在构造函数里定义的"特权"函数才能间接访问.
我们再把我们的视野移到整个内部属性集合,像[[Class]],[[Extensible]]等.

内部属性 访问方法
[[Prototype]] Object.getPrototypeOf(obj) , obj.__proto__(访问器属性,类似于方法)
[[class]] Object.prototype.toString.call(obj)
[[Extensible]] Object.isExtensible , Object.preventExtensions

那么,我们如何自定义一个函数的私有属性呢
在js中,我们通常通过闭包来实现私有属性.
代码:

function Student(num,str){
var grade = num;
var name = str;
this.getGrade = function (){
return grade;
}
this.getName = function(){
return name;
}
}
var s = new Student(98,‘peter’);
console.log(s);
console.log(s.grade);//undefined,不能直接访问私有属性
s.name = ‘selena’;//对象新建了一个自身属性name,不是私有属性[[name]]
console.log(s.name);//selena,访问自身属性
console.log(s.getName());//peter,通过特权方法getName()访问私有属性

运行结果:
\
这种实现的优缺点总结:
1.私有属性和特权函数只能在构造函数中创建
2.闭包的使用增加了资源占用,可能会导致一些问题

对象的保护

阻止对象的扩展(Preventing Extension)
效果:禁止向对象添加新属性,仍可以删除已有属性
实现途径:Object.preventExtensions(obj)
检查是否已阻止:Object.isExtensible(obj)

封闭对象(Sealing)
效果:禁止添加新属性,全部已有属性"unconfigurable"(不可更改属性的特性值,不可删除自身属性),但基于历史原因,仍可以将writable改为read-only.
实现途径:Object.seal(obj)
检查对象是否已封闭:Object.isSealed(obj)

冻结对象(Freezing)
效果:使所有属性变为只读,同时不可扩展(添加新属性),不可修改属性特性,不可删除属性
实现途径:Object.freeze(obj)
检查对象是否已冻结:Object.isFrozen(obj)

严格模式

严格模式是ECMAScript的一部分.可以灵活切换,可以是整个文件,也可以仅在一个函数内

启用方式:
整个文件----将’use strict’放在在文件开始处
某个函数----将’use strict’放在在函数开始处

对安全性的需求是严格模式使用的主要动机

严格模式特征:

安全性:极严格地限制eval()的使用,with语句禁止使用 全局变量使用之前必须被明确地声明(不会再自动生成),这有助于预防输入上的错误 未使用new调用构造函数时:
在严格模式出现之前,this是绑定到全局变量的,这导致会有属性被添加到这个对象.
严格模式中,如果构造函数不是经new调用的,那么this是绑定到undefined的,而且通常会有一个exception被抛出.

烦人的报错:尝试修改一个只读的属性的值或者删除一个不可配置的属性,会丢出exception.

不再支持八进制数:严格模式中,以0开头的数不会再被理解成八进制,0100就是十进制的100,而不是八进制的64.

参数对象:arguments.callee和arguments.caller属性被排除掉(基于安全原因:这样使得他们不被外部代码发现)

函数参数:禁止出现与形参同名的参数或变量名.

点击复制链接 与好友分享!回本站首页
相关TAG标签 js 对象 类型
上一篇:Vue面试中常问知识点
下一篇:jQuery解析
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站