我们先从盘古开天辟地时捋一捋对象:

从宏观内容来讲,javascript是一个属性的集合,包括值,函数,而整个集合也可以类比为一个对象。

js = {
  a的变量名: a的值,
  ...
  
  函数b: function () {}
  ...
}

注: 这里的js指的是javascript对象(ECMAscript对象),而不是DOM和BOM对象。

紧接着我们听到一个“传说”:‘javascript中一切都是对象’  ,或者说是有这么一个说法,但到底说的正确还是不正确,我们还需要自己追根溯源,挖掘一下:

从js来讲,变量和方法之间联系很紧密,变量可以通过原生js对象的构造方法创建,而方法又可以通过创建的变量(“对象”)调用,注意这里的对象是带了引号的,这就说明它不是真正意义上的对象,下文会说明原由。

js中一共由6中基本数据类型:number,string,boolean,null,undefined,symbol(es6新增)

从属性值方面讲:一个变量可以通过两种方式创建:

1. 由于js为弱类型语言,所以可直接赋值创建

var a = 1;
console.log(typeof a) // number

2. 由原生对象通过构造函数创建

var b = new Number(1);
console.log(typeof b) // object

为确定它们都是数字,我们可以判断一下:

console.log(a == b)   // true

由此可知,a和b只是创建方式不同,而a也确实是基本数据类型,但是,基本数据类型又能否向对象一样进行添加属性的操作呢,答案是可以的:

        var a = 1;
a.prop = 2; // 不会报错
console.log(a) //
console.log(a.prop) // undefined
console.log(a.toString()) // 1 (字符串)

那么变量a的数据类型为基本数据类型,却又可以进行对象赋值操作(这里只能够赋值,但赋值没有成功),还可以调用对象的方法。

回想一下,我们经常是通过最简单的方法定义变量(基本类型可以通过直接赋值,引用类型可以通过字面量),而这些方法是为了简化操作。当基本数据类型触发对象行为时,系统会为基本数据类型创建一个包装对象,当对象行为完成后,该包装对象即被销毁。

现在回来说,js中的一切是不是对象,主要在于对基本数据类型的操作,常规操作时,它只是基本数据类型,特殊使用时,基本类型又会成为包装对象。

由此,可以总结出,js的一切是不是对象,完全在于你的代码习惯,或者代码功能,确实没有一个确定的答案,主要在于你个人的理解。就像人妖到底是人还是妖,完全在于你在生活中怎么去看待。

源头说的差不多了,下面我们来具体说明:

在js中所有通过对象创建的对象,都有一个原型。这些对象都有一个通过原型链接的父级,而这些链接起对象的原型就是原型链。

在js中,除了null(空对象)和Object.prototype之外,都有原型。通俗来讲,它们没有“爹”。空对象,顾名思义,一切皆空,什么也不是,什么也没有。而Object.prototype是原型链的最顶端,如果你是科班出身,那么你一定听说过链表,这里的Object.prototype也就相当于是链表的根节点。

做人要 追源溯果,写代码也一样。我们可以通过Object.creat方法创建指定原型的对象

var a = Object.create(Number.prototype)

a的父级就是Number,Number的父级是Object。下图可以辅助理解

此时,a便可以使用Number.prototype对象和Object.prototype中的方法。

操作属性

对象的属性还存在属性的特性用以控制对象的属性:值(value),操作性(configurable),可写性(writable),枚举性(numerable)。

        var obj = {
a: 1,
b: 2
}
Object.defineProperty(obj, 'b', {
value: 5,
enumerable:false
})
console.log(obj) // {a: 1, b: 5}
for (var i in obj) {
console.log(i) // a
}

configurable:能否使用delete、能否更改特性,false为不可重新定义

在此要注意,通过Object.defineProperty()创建的属性,以上三个特性的默认值都是false。

enumerable值为false的属性会影响三个过程:

1. 通过for  in遍历对象的过程,无法遍历不可枚举属性

2.通过Object.keys(obj)返回属性值的过程,无法获得obj中的不可枚举属性名

3.JSON.stringify(obj)将对象转换为字符串的过程,只返回可枚举属性

检测属性

当我们需要检测属性时,可以通过以下三种方式:

        var obj = {
a: 1,
b: 2
}
Object.defineProperty(obj, 'a', {
value: 5,
enumerable:false
})
// 方法1 (可判断多有属性,包括继承的属性)
console.log('a' in obj) // true
// 方法2 (只可判断自身的属性)
console.log(obj.hasOwnProperty('a')) // true
// 方法3 (只可判断自身的可枚举属性)
console.log(obj.propertyIsEnumerable('a')) // false
console.log(obj.propertyIsEnumerable('b')) // true

删除属性

在删除属性时,delete只会断开属性与宿主对象之间的联系,而不是操作此属性。删除对象的属性时,要深层遍历防止属性值也为对象的情况。

        var obj = {
a: {
x: 1
},
b: 0
}
var obj2 = obj.a;
delete obj.a
console.log(obj) // {b: 0}
console.log(obj2.x) //

存取器属性

类似于外观模式下的get与set方法,get 返回相应的值,set则用于根据场景的不同选择性的设置属性值。

        var stu = {
name: 'kevin',
age: 15,
get change () {
return this.name
},
set change (name) {
if (this.age >= 18) this.name = name
else throw '未满18岁不可改名'
}
}
console.log(stu.change) // kevin
stu.change = 'pomelo'
console.log(stu.name) // 抛出异常

注:

1.存取器属性是可以继承的

2.存取器属性不含有value和writable特性,get代替了value,而set则代替了writable

js对象系列【一】深层理解对象与原型的更多相关文章

  1. 深入理解javascript对象系列第一篇——初识对象

    × 目录 [1]定义 [2]创建 [3]组成[4]引用[5]方法 前面的话 javascript中的难点是函数.对象和继承,前面已经介绍过函数系列.从本系列开始介绍对象部分,本文是该系列的第一篇——初 ...

  2. js面向对象的程序设计 --- 上篇(理解对象)

    前言 ECMAScript中没有类的概念,因此它们的对象与基于类的语言中的对象有所不同. ECMA-262把对象定义为:"无序的集合属性,其属性可以包含基本值,对象或者函数".正因 ...

  3. javascript系列--认识并理解构造函数,原型和原型链

    一.前言 介绍构造函数,原型,原型链.比如说经常会被问道:symbol是不是构造函数:constructor属性是否只读:prototype.[[Prototype]]和__proto__的区别:什么 ...

  4. JS面向对象的程序设计之理解对象

    一.对象定义 (1)ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同: (2)ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值.对象或者函数” 二. ...

  5. 【 D3.js 入门系列 --- 7 】 理解 update, enter, exit 的使用

    在前面几节中反复出现了如下代码: svg.selectAll("rect") .data(dataset) .enter() .append("rect") 当 ...

  6. 深入理解javascript对象系列第二篇——属性操作

    × 目录 [1]查询 [2]设置 [3]删除[4]继承 前面的话 对于对象来说,属性操作是绕不开的话题.类似于“增删改查”的基本操作,属性操作分为属性查询.属性设置.属性删除,还包括属性继承.本文是对 ...

  7. JavaScript--我发现,原来你是这样的JS:面向对象编程OOP[1]--(理解对象和对象属性类型)

    一.介绍 老铁们,这次是JS的面向对象的编程OOP(虽然我没有对象,心累啊,但是可以自己创建啊,哈哈). JS高程里第六章的内容,这章内容在我看来是JS中很难理解的一部分.所以分成三篇博客来逐个理清. ...

  8. JS--我发现,原来你是这样的JS:面向对象编程OOP[1]--(理解对象和对象属性类型)

    一.介绍 老铁们,这次是JS的面向对象的编程OOP(虽然我没有对象,心累啊,但是可以自己创建啊,哈哈). JS高程里第六章的内容,这章内容在我看来是JS中很难理解的一部分.所以分成三篇博客来逐个理清. ...

  9. JS面向对象系列教程 — 对象的基本操作

    面向对象概述  面向对象(Object Oriented)简称OO,它是一种编程思维,用于指导我们如何应对各种复杂的开发场景. 这里说的对象(Object),意思就是事物,在面向对象的思维中,它将一 ...

随机推荐

  1. Ansible自动化运维笔记2(Ansible的组件介绍)

    1.Ansible Inventory (1)静态主机文件 默认的ansible invetory是/etc/hosts文件,可以通过ANSIBLE_HOSTS环境变量或者通过运行命令的时候加上-i ...

  2. 总结MySQL大数据量下如何进行优化

    写在建库前: 在确定数据库业务后.建立数据库表格时,就应对一些常见问题有所考虑,以避免在数据增长一段时间后再做应对,可能造成时间及维护成本增加: 数据的月增量,年增量 数据的快速增长点 是否需要触发器 ...

  3. Hive数据倾斜总结

    倾斜的原因: 使map的输出数据更均匀的分布到reduce中去,是我们的最终目标.由于Hash算法的局限性,按key Hash会或多或少的造成数据倾斜.大量经验表明数据倾斜的原因是人为的建表疏忽或业务 ...

  4. Xmind8 Pro安装教程 Windows

      xmind是一款优秀的思维导图制作软件,这一点相信不用太多解释. 尤其作为测试人员导出测试用例为excel极其方便.网上xmind的破解方法加自己琢磨,重新整理了破解步骤. 亲测可以永久激活截止2 ...

  5. 经典案例之MouseJack

    引言:在昨天的文章<无线键鼠监听与劫持>中,我们提到今天会向您介绍一个无线键鼠的监听与劫持的经典案例,<MouseJack>:MouseJack能利用无线鼠标和键盘存在的一些问 ...

  6. 为你的APK进行数字签名

    摘要: 我们需要为 APK进行数字签名,这样才能发布到 Google Play商店.解决方法很简单,使用 Java的keytool命令创建证书并在 Gradle构建文件的 signingConfigs ...

  7. DOS下串口通信程序来传送文件的源代码

    接收程序: #include <dos.h>#include <fstream.h>#include <conio.h>#include <stdio.h&g ...

  8. PHPmysqli的 其他函数 从数据库中读出数据并且打印出来

    <?php // 认识其他mysqli其他函数 header( 'Content-Type:text/html;charset=utf-8 '); require 'prepareSrarmen ...

  9. Error:dijit.tree.TreeStoreModel:root query returned 0 items

    1.错误描述 error loading root:                                            Tree.js(第341行) Error:dijit.tre ...

  10. 芝麻HTTP:Python爬虫入门之Cookie的使用

    为什么要使用Cookie呢? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密) 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想抓 ...