深入javascript之对象
前言
这是读书笔记第二篇,看完之后突然发现自己对js的内置的一些东西还是了解的不够全面,很多方法见都没见过,啥用都不知道,这是非常不可取的。码农好歹也得眼熟啊,晓都不晓得后面的学习还怎么进行下去。。。赶紧做笔记吧~文中如有错误不当不出,欢迎指出~
创建一个对象
var obj = {} //字面量创建
var obj = new Object() //构造函数创建
2种创建方式是完全一样的,一般书写我们都采用字面量。
复制对象
首先明确一点,借用红宝书一句话,对于对于js中的赋值传参等操作,传递的都是值,不关是基本类型还是引用类型,传递的都是值,只是引用类型传递的是一个内存地址的值。不同对象如果引用同一块内存地址,还是会相互影响的。对象就是引用类型,这里介绍2种简单的方法来复制对象,又能不相互影响。
//安全的json序列对象,只能复制键值对,不能复制函数
JSON.parse(JSON.stringify(obj))
//es6新增的内置方法复制对象
Object.assign({},obj1,obj2...)
对象属性的特性
一般我们看到的对象就是一对对键值对,其实内部并没有我们想象的这么简单。看以下代码:
var a = {
a:2,
fuc:function() {
console.log('xxx')
}
}
//通过Object.getOwnPropertyDescriptors获取对象属性
Object.getOwnPropertyDescriptors(a)
a: {
configurable: true //可配置
enumerable: true //可枚举
value: 2
writable: true // 可写
}
.....
我们看到a属性除了一个值外,还有3个默认特性,继续看:
var myObject = {};
Object.defineProperty( myObject, "a", {
value: 2,
writable: false, // not writable!
configurable: true,
enumerable: true
} );
myObject.a = 3;
myObject.a; // 2
通过Object.defineProperty定义了一个a属性,该属性不可写,结果上我们已经无法修改属性值。
var myObject = {
a:2
};
myObject.a; // 2
delete myObject.a;
myObject.a; // undefined
Object.defineProperty( myObject, "a", {
value: 2,
writable: true,
configurable: false,
enumerable: true
} );
myObject.a; // 2
myObject.a = 5;
myObject.a; // 5
delete myObject.a;
myObject.a; // 5
设置属性不可配置,我们看到我们无法再删除这个属性,但是仍然可以修改值。enumerable特性我们就比较熟悉了,for in循环枚举属性就是枚举可枚举的属性,如果我们设置为false ,这个属性就不会被枚举。
要注意有一个小小的例外:即便属性是configurable:false, 我们还是可以把writable的状态由true改为false,但是无法由false改为true。
自定义属性的set和get
var myObject = {
// 给 a 定义一个getter
get a() {
return this._a_;
},
// 给 a 定义一个setter
set a(val) {
this._a_ = val * 2;
}
};
myObject.a = 10 ;
myObject.a //20
上面代码我们复写了a属性的获取和设置方法,没有赋值直接获取会返回undefined,通过这个可以使我们创造出一些有趣的东西,vue源码中我们就能看到很多实际的例子。
propertyIsEnumerable(..)会检查给定的属性名是否直接存在于对象中(而不是在原型链上)并且满足enumerable:true。
Object.keys(..)会返回一个数组,包含所有可枚举属性,Object.getOwnPropertyNames(..)会返回一个数组,包含所有属性,无论它们是否可枚举。
in和hasOwnProperty(..)的区别在于是否查找[[Prototype]]链,然而,Object.keys(..)和Object.getOwnPropertyNames(..)都只会查找对象直接包含的属性。
内置方法这里不再赘述,实时了解ecmascript的动态,掌握新的内容是非常必要的,我们可能永远用不到一些内置方法,但是我们确保得先知道它,不然在需要的时候可能会像无头苍蝇乱撞或者使用一些比较蠢的老方法。
面向对象编程
什么是面向对象编程?这个问题是我入坑时无法解惑的一个问题。但是随着业务的不断积累,这个问题会变得越来越清晰。
我们首先会介绍面向类的设计模式:实例化(instantiation)、继承(inheritance)和(相对)多态(polymorphism)。
类理论
类/继承描述了一种代码的组织结构形式——一种在软件中对真实世界中问题领域的建模方法。
面向对象编程强调的是数据和操作数据的行为本质上是互相关联的(当然,不同的数据有不同的行为),因此好的设计就是把数据以及和它相关的行为打包(或者说封装)起来。这在正式的计算机科学中有时被称为数据结构。
举例来说,用来表示一个单词或者短语的一串字符通常被称为字符串。字符就是数据。但是你关心的往往不是数据是什么,而是可以对数据做什么,所以可以应用在这种数据上的行为(计算长度、添加数据、搜索,等等)都被设计成String类的方法。
所有字符串都是String类的一个实例,也就是说它是一个包裹,包含字符数据和我们可以应用在数据上的函数。
我们还可以使用类对数据结构进行分类,可以把任意数据结构看作范围更广的定义的一种特例。
我们来看一个常见的例子,“汽车”可以被看作“交通工具”的一种特例,后者是更广泛的类。
“在我们的软件中,对不同的交通工具重复定义“载人能力”是没有意义的。相反,我们只在Vehicle中定义一次,定义Car时,只要声明它继承(或者扩展)了Vehicle的这个基础定义就行。Car的定义就是对通用Vehicle定义的特殊化。
虽然Vehicle和Car会定义相同的方法,但是实例中的数据可能是不同的,比如每辆车独一无二的VIN(Vehicle Identification Number,车辆识别号码),等等。
这就是类、继承和实例化。
类的另一个核心概念是多态,这个概念是说父类的通用行为可以被子类用更特殊的行为重写。实际上,相对多态性允许我们从重写行为中引用基础行为。
'类'设计模式
你可能从来没把类作为设计模式来看待,讨论得最多的是面向对象设计模式,比如迭代器模式、观察者模式、工厂模式、单例模式,等等。从这个角度来说,我们似乎是在(低级)面向对象类的基础上实现了所有(高级)设计模式,似乎面向对象是优秀代码的基础。
考虑到尽可能容易理解。这里摘录了基本概念,这是一个抽象的东西,我们在撸码过程中可能不知不觉就已经在实践这种理念,但是没有看过这种概念的人可能会一下子说不出来。
这些概念实际上无法直接对应到JavaScript的对象机制,因此JavaScript开发者用一系列方法去模拟实现面相编程,比如混入,mixin。
这里说说在下对面相对象编程的理解 ,面向对象编程其实就是一类事物的抽象。比如 人,都会说话,走路,但是可能有的人说汉语,有的人说英语,对于这种广泛的抽象中又有非常多的特例,我们可以对其建模:
var Person = function(){
this.name = 'person',
this.age = '',
this.talk = function(){alert('talk')},
this.walk = function(){alert('wall')}
}
var p1 = new Person()
var p2 = new Person()
p1.name = 'xu'
p2.name = 'pp'
...
我们构造了一个person函数,通过person函数构造了2个人类实例,一个名字是xu一个名字是pp。。会说话,会走路。
ES6中的class语法
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
var d = new Dog('Mitzie');
// 'Mitzie barks.'
d.speak();
es6的class语法糖让我们模拟面相编程变得更加规范,这里引用mdn的一个例子,更具体的建议可以自己找文章看,毕竟这是一个js一个非常重要的知识。
后记
要想完全搞懂一些概念,抽象的东西,其实并不是一天两天,一两篇文章就能做到的,我的建议是,理论,实践,理论,实践,一个螺旋上升的过程。感觉笔记内容不是很深入,毕竟是读书笔记和自己的一些理解看法,就当深入的程度不是那么深吧~
如果觉得本文对你有所帮助,就star一下吧~大传送之术! 我的博客Github
深入javascript之对象的更多相关文章
- javascript 全局对象--w3school
JavaScript全局对象 1. decodeURI()解析某个编码的URI. 2.decodeURInComponent()解析一个编码的URI组件. 3.encodeURI()把字符串编码为U ...
- JavaScript Json对象和Json对象字符串的关系 jsonObj<->JsonString
JavaScript Json对象和Json对象字符串的关系 jsonObj<->JsonString 如下示例: 直接写的a1就是一个Json对象,a2 就是一个Json对象字符串; 通 ...
- 从零构建JavaScript的对象系统
一.正统的类与继承 类是对象的定义,而对象是类的实例(Instance).类不可直接使用,要想使用就必须在内存上生成该类的副本,这个副本就是对象. 以Java为例: public class Grou ...
- 关于javascript自定义对象(来自网络)(最近几天不会的)
javascript定义对象的几种简单方法 1.构造函数方式,全部属性及对象的方法都放在构造方法里面定义 优点:动态的传递参数 缺点:每创建一个对象就会创建相同的方法函数对象,占用大量内存 funct ...
- 据说每个大牛、小牛都应该有自己的库——JavaScript原生对象拓展
在据说每个大牛.小牛都应该有自己的库——框架篇中我扬言要做个小牛,没想到一天没更新,小伙儿伴们就戏谑的问我,油哥是不是要太监了?其实事情是这个样子的,这不是太监的节奏,一是,关于写个自己的库的想法由来 ...
- JavaScript RegExp 对象
JavaScript RegExp 对象 RegExp 对象用于规定在文本中检索的内容. 什么是 RegExp? RegExp 是正则表达式的缩写. 当您检索某个文本时,可以使用一种模式来描述要检索的 ...
- JavaScript String 对象
JavaScript String 对象 String 对象 String 对象用于处理文本(字符串). String 对象创建方法: new String(). 语法 var txt = new S ...
- JavaScript Math 对象
JavaScript Math 对象 Math 对象 Math 对象用于执行数学任务. Math 对象并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math(). 语法 var ...
- JavaScript Number 对象
JavaScript Number 对象 Number 对象 Number 对象是原始数值的包装对象. Number 创建方式 new Number(). 语法 var num = new Numbe ...
- JavaScript Array 对象
JavaScript Array 对象 Array 对象 Array 对象用于在变量中存储多个值: var cars = ["Saab", "Volvo", & ...
随机推荐
- 201521123006 《java程序设计》 第10周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...
- java课程设计-表达式运算(团队博客)
1 团队课程设计博客 1 团队名称.团队成员介绍 团队名称 奔跑吧土拨鼠 团队成员 洪亚文 201521123065 网络1513 郑晓丽 201521123066 网络1513 2 项目git地址 ...
- XML解析【介绍、DOM、SAX详细说明、jaxp、dom4j、XPATH】
什么是XML解析 前面XML章节已经说了,XML被设计为"什么都不做",XML只用于组织.存储数据,除此之外的数据生成.读取.传送等等的操作都与XML本身无关! XML解析就是读取 ...
- 离线安装 Cloudera Manager 5 和 CDH5.10
关于CDH和Cloudera Manager CDH (Cloudera's Distribution, including Apache Hadoop),是Hadoop众多分支中的一种,由Cloud ...
- 框架应用:Mybatis (一) - 入门案例
ORM框架 在实际开发中,工程中本质的任务是从数据库中获取数据,然后对数据进行操作,又或者写入数据.开发时语言是大多是面向对象的工程语言,这个时候就必须进行工程语言和数据库连接语言的转换,也就是所谓的 ...
- 异常 SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase]
使用Spring 的JDBCtemplate 调用数据库的时候 出现了如下的问题 SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-S ...
- 详解 HTTPS 移动端对称加密套件优
近几年,Google.Baidu.Facebook 等互联网巨头大力推行 HTTPS,国内外的大型互联网公司很多也都已启用全站 HTTPS. Google 也推出了针对移动端优化的新型加密套件 Cha ...
- mybatis枚举映射成tinyint
第一步:定义顶级枚举接口 public interface BaseEnum<E extends Enum<?>, T> { public T getCode(); publi ...
- vue练手小项目--眼镜在线试戴
最近看到了一个眼镜在线试戴小项目使用纯js手写的,本人刚学习vue.js没多久,便试试用vue做做看了,还没完善. 其中包括初始图片加载,使用keywords查找,父子组件之间传递信息,子组件之间传递 ...
- Windows下 如何添加开机启动项
Windows XP,Windows 7: 开始 ----> 所有程序 ----> 启动, 右键打开"启动"这个文件夹, 把想开机自动启动的软件快捷方式拖进去即可. ( ...