js对象的深入理解(六)
一、对象的创建(四种模式)
1.工厂模式
工厂模式示例:
function createPerson(name,age){
var obj = {
name:name,
age:age,
sayName:function(){}
};
return obj;
}
var p1 = createPerson("tom",12);
var p2 = createPerson("jerry",10);
缺点:
a.创建的对象都是Object类型【无法识别对象】
b.每个对象相同的方法【不存储在相同的存储空间】占据不同的内存空间【对象相同的方法重复创建内存空间,造成内存冗余】
2.构造函数模式
构造函数示例:
function Person(name,age){
this.name = name;
this.age = age;
this.sayName = function(){};
}
var p1 = new Person("tom",12);
var p2 = new Person("jerry",10);
new关键字的作用:
a.创建了一个新实例对象
b.使构造方法中的this【作用域】指向该新实例对象
c.执行构造函数中的代码
d.返回这个新实例对象
优点:可以识别对象
缺点:实例对象的相同方法【不存储在相同的存储空间】在创建实例时均被重复创建【代码、内存冗余】
解决对象相同方法的创建冗余问题:
可以在全局范围中声明一个函数,然后将引用传递给对象中的函数属性。但是这样做会导致全局函数过多,体现不了对象的封装性
3.原型模式
原型模式示例:
function Person(){}
Person.prototype.name = 'tom';
Person.prototype.age = 12;
Person.prototype.sayName = function(){};
var p1 = new Person();
p1.name = 'jerry';
var p2 = new Person;
p2.name = 'terry';
优点:解决了对象的相同方法存储空间重复调用的问题【解决了代码、内存冗余问题】
缺点:同一类型的对象的相同属性共用原型对象中的对应属性的属性值【对象间的隔离性较差】
4.组合模式(构造函数-原型模式)【目前在ECMAScript中使用最广泛,认同度最高的一种创建自定义类型的方法】
a.在构造函数模式中定义对象自身的属性及与其他相同类型对象的不同的方法
b.在原型模式中定义同类型对象的相同方法
组合模式示例:
function Person(name,age){
this.name = name,
this.age = age,
this.friends = []
}
Person.prototype = {
constructor : Person,
sayName:function(){}
}
var p1 = new Person("terry",11);
var p2 = new Person("larry",12);
p1.friends.push("tom");
p2.friends.push("jack");
onsole.log(p1); //["tom"]
console.log(p2); //["jack"]
优点:可以识别对象,也解决了对象的相同方法存储空间重复调用的问题【解决了代码、内存冗余问题】,隔离性较差问题也不存在
二、对象的属性类型
1、对象属性的特性【configurable、enumerable、writable、value】
[[Configurable]]:【默认为true】
a.是否可以使用delete删除该属性值
b.是否可以修改相应属性的特性
[[Enumerable]]:【默认为true】
是否可以通过for-in循环遍历该属性。【是否可枚举】
[[Writable]]: 【默认为true】
是否可以修改相应属性的值。
[[Value]]: 【默认为true】
设置相应属性的数据值 name:jacky
要修改属性默认的特性,必须使用ECMAScript5的Object.defineProperty()方法
访问器属性:【可以隐藏真实属性的数据,利用其对应的访问器属性对外公开展示。即:我们看到的可能不是真正的属性值】
访问器属性不包含数据值,包含一对setter,getter方法。
[[Get]] 在获取属性时调用的函数,默认为undefined
[[Set]] 在写入属性时调用的函数,默认为undefined
修改单个属性特性值需要使用下面方法:
defineProperty(属性所在的对象,属性的名字,一个描述符对象);
当configurable:false 时,不能修改该属性特性的特性值
2.对属性特性的相关操作方法【使用下面方法定义的属性其configurable特性值一般为false】
a、Object.defineProperty(属性对应的对象,属性的名字,一个描述符对象)【定义单个属性】
eg:
var obj = {
name:'tom',
age:21
};
Object.defineProperties(obj,'name'{
writable:false //obj对象中的name属性不可修改
});
obj.name = 'jerry'; //这条语句无效,name属性的writable特性值为false不可修改
b、Object.defineProperties(属性对应的对象,所需要定义的多个属性的描述对象)【定义多个属性】
eg:
var obj = {
name:'tom',
_age:21
};
Object.defineProperties(book,{
_age:{//数据属性
value:22,
configurable:false //_age属性不能delete,不能重新定义该属性
},
age:{//访问器属性
get:function(){
return this._age-2
},
set:function(age){
this._age = age
}
}
});
console.log(obj.age); //20
c、Object.getOwnPrototypeDescriptor(属性对应的对象,属性的名字)【读取属性的特性信息】
var descriptor = Object.getOwnPropertyDescriptor(obj,"_age");
console.log(descriptor.value); //
console.log(descriptor.configurable) //false
js对象的深入理解(六)的更多相关文章
- JS对象原型的理解
基于原型的语言 JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板.从原型继承方法和属性.原型对象 ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- js对象系列【一】深层理解对象与原型
我们先从盘古开天辟地时捋一捋对象: 从宏观内容来讲,javascript是一个属性的集合,包括值,函数,而整个集合也可以类比为一个对象. js = { a的变量名: a的值, ... 函数b: fun ...
- js 模块化的一些理解和es6模块化学习
模块化 1 IIFE 2 commonjs 3 浏览器中js的模块化 4 简单理解模块加载器的原理 5 es6 之前在参加百度前端技术学院做的小题目的时候,自己写模块的时候 都是写成立即调用表达式( ...
- js赋值运算的理解
简介 js引擎由于为了效率,很多时候的非直接量赋值都不是copy一份在赋值给新的变量,而是一个引用 ps:直接量:直接值数字字符串等 为什么使用len = doms.length; 里的len效率要比 ...
- JSON与js对象序列化
JavaScript对象表示法(JavaScript Object Notation,简称JSON)是一种轻量级的数据交换格式,它基于js字面量表示法,是js的一个子集.虽然是一个js的子集但是他与语 ...
- js 对象深复制,创建对象和继承
js 对象深复制,创建对象和继承.主要参考高级编程第三版,总结网上部分资料和自己的代码测试心得.每走一小步,就做一个小结. 1.对象/数组深复制 一般的=号传递的都是对象/数组的引用,如在控制台输入 ...
- 我对 impress.js 源码的理解
源码看了两天,删掉了一些优化,和对 ipad 的支持,仅研究了其核心功能的实现,作以下记录. HTML 结构如下: <!doctype html> <html lang=" ...
- [JS] 面向对象的5种写法和拓展JS对象的写法
面向对象的JAVA 最开始当然是对象的定义了 收集了以下的五种写法 //第1种写法 function Circle(r) { this.r = r; } Circle.PI = 3.14159; C ...
随机推荐
- java字符串格式化性能对比String.format/StringBuilder/+拼接
String.format由于每次都有生成一个Formatter对象,因此速度会比较慢,在大数据量需要格式化处理的时候,避免使用String.format进行格式化,相反使用StringUtils.l ...
- R3300L运行CoreELEC, EmuELEC和Armbian
R3300L的参数 CPU: S905LRAM: Samsung K4B4G1646E-BCMA 512MB * 2 = 1GBROM: Samsung KLM8G1WEPD-B031 8GB eMM ...
- 010 vue使用render方法渲染组件
1.普通的组件渲染方式 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...
- 移除 WordPress 自动加载的 jQuery,使用自定义 jQuery 版本
WordPress 使用的 jQuery 版本由于需要考虑到很多安全稳定的因素,所以一般不会使用最新版本的 jQuery, 可以通过以下方式移除 WordPress 自定加载的 jQuery,并加载自 ...
- 【转】Python查找某文件夹下的所有excel文件
# -*- coding: utf-8 -*- # author:baoshan import os dirname = r'D:\0.shenma\01.聊城资料\01.数据资料\02.聊城年鉴数据 ...
- word2vec原理总结
一篇很好的入门博客,http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/ 他的翻译,https://www. ...
- IntelliJ IDEA 安装使用 FindBugs 代码分析详述
1 下载 2 重启idea 选中文件,右键 附:一些常见的错误信息 Bad practice 代码中的一些坏习惯 Class names should start with an upper case ...
- nginx安装和命令
1. nginx安装 1.1 mac上安装 brew search nginx brew install nginx 1.2 windows上安装 下载nginx.zip,解压到D盘,发送快捷方式到桌 ...
- 本地win下JConsole监控远程linux下的JVM
环境:服务器端: Linux + jdk1.7.0_75 + tomcat 7本地: Win + jdk1.7.0_55 一.修改/etc/hosts文件 hostname -i 如果显示127.0. ...
- java修改文件所有者及其权限
1.设置所有者 管理文件所有者 Files.getOwner()和Files.setOwner()方法 要使用UserPrincipal来管理文件的所有者 (1)更改文件的所有者 import jav ...