深入理解javascript对象系列第一篇——初识对象
前面的话
javascript中的难点是函数、对象和继承,前面已经介绍过函数系列。从本系列开始介绍对象部分,本文是该系列的第一篇——初识对象
对象定义
javascript的基本数据类型包括undefined、null、boolean、string、number和object。对象和其他基本类型值不同的是,对象是一种复合值:它将许多值(原始值或者其他对象)聚合在一起,可通过名字访问这些值
于是,对象也可看做是属性的无序集合,每个属性都是一个名值对。属性名是字符串,因此我们可以把对象看成是从字符串到值的映射
关于复合值和原始值的详细区别移步至此
对象创建
有以下三种方式来创建对象,包括new构造函数、对象直接量和Object.create()函数
【1】new构造函数
使用new操作符后跟Object构造函数用以初始化一个新创建的对象
var person = new Object();
//如果不给构造函数传递参数可以不加括号 var person = new Object;
person.name = 'bai';
person.age = 29;
//创建无属性的空对象
var cody1 = new Object();
var cody2 = new Object(undefined);
var cody3 = new Object(null);
console.log(typeof cody1,typeof cody2, typeof cody3);//object object object
如果该参数是一个对象,则直接返回这个对象
var o1 = {a: 1};
var o2 = new Object(o1);
console.log(o1 === o2);// true var f1 = function(){};
var f2 = new Object(f1);
console.log(f1 === f2);// true
如果是一个原始类型的值,则返回该值对应的包装对象
//String {0: "f", 1: "o", 2: "o", length: 3, [[PrimitiveValue]]: "foo"}
console.log(new Object('foo')); //Number {[[PrimitiveValue]]: 1}
console.log(new Object(1)); //Boolean {[[PrimitiveValue]]: true}
console.log(new Object(true));
若Object()函数不通过new而直接使用,则相当于转换方法,可以把任意值转换为对象
[注意]undefined和null会转换为一个空对象
var uObj = Object(undefined);
var nObj = Object(null);
console.log(Object.keys(uObj));//[]
console.log(Object.keys(nObj));//[]
如果Object()的参数是一个对象,则直接返回原对象
var o = {a:1};
var oObj = Object(o);
console.log(Object.keys(oObj));//['a']
利用这一点,可以写一个判断变量是否为对象的函数
function isObject(value) {
return value === Object(value);
}
isObject([]) // true
isObject(true) // false
【2】对象字面量
javascript提供了叫做字面量的快捷方式,用于创建大多数原生对象值。使用字面量只是隐藏了与使用new操作符相同的基本过程,于是也可以叫做语法糖
对象字面量是由若干名值对组成的映射表,名值对中间用冒号分隔,整个映射表用花括号括起来
不同属性之间用逗号分隔,属性名可以是任意字符串,属性值可以是任意类型表达式,表达式的值是属性值
//等价于var person = new Object();
var person = {};
var person = {
name : 'bai',
age : 29,
5 : true
};
使用对象字面量的方法来定义对象,属性名会自动转换成字符串
//同上
var person = {
'name' : 'bai',
'age' : 29,
'5' : true
};
[注意]一般地,对象字面量的最后一个属性后的逗号将忽略,但在IE7-浏览器中导致错误
//IE7-浏览器中报错 SCRIPT1028: 缺少标识符、字符串或数字
var person = {
name : 'bai',
age : 29,
5 : true,
};
【3】Object.create()
ES5定义了一个名为Object.create()的方法,它创建一个新对象,第一个参数就是这个对象的原型,第二个可选参数用以对对象的属性进行进一步描述
var o1 = Object.create({x:1,y:1}); //o1继承了属性x和y
console.log(o1.x);//
可以通过传入参数null来创建一个没有原型的新对象,但通过这种方式创建的对象不会继承任何东西,甚至不包括基础方法。比如toString()和valueOf()
var o2 = Object.create(null); // o2不继承任何属性和方法
var o1 = {};
console.log(Number(o1));//NaN
console.log(Number(o2));//Uncaught TypeError: Cannot convert object to primitive value
如果想创建一个普通的空对象(比如通过{}或new Object()创建的对象),需要传入Object.prototype
var o3 = Object.create(Object.prototype); // o3和{}和new Object()一样
var o1 = {};
console.log(Number(o1));//NaN
console.log(Number(o3));//NaN
Object.create()方法的第二个参数是属性描述符
var o1 = Object.create({z:3},{
x:{value:1,writable: false,enumerable:true,configurable:true},
y:{value:2,writable: false,enumerable:true,configurable:true}
});
console.log(o1.x,o1.y,o1.z);//1 2 3
对象组成
对象是属性的无序集合,由键名和属性值组成
【键名】
对象的所有键名都是字符串,所以加不加引号都可以,如果不是字符串也会自动转换成字符串
var o = {
'p': 'Hello World'
};
var o = {
p: 'Hello World'
};
var o ={
1: 'a',
3.2: 'b',
1e2: true,
1e-2: true,
.234: true,
0xFF: true,
};
//Object {1: "a", 100: true, 255: true, 3.2: "b", 0.01: true, 0.234: true}
o;
[注意]如果键名不符合标识符命名规则,则必须加上引号,否则会报错
//Uncaught SyntaxError: Unexpected identifier
var o = {
1p: 123
} var o = {
'1p': 123
}
【属性值】
属性值可以是任何类型的表达式,最终表达式的结果就是属性值的结果
var o ={
a: 1+2
}
console.log(o.a);//
如果属性值为函数,则通常把这个属性称为“方法”
var o = {
p: function (x) {
return 2 * x;
}
};
o.p(1);//
由于对象的方法就是函数,因此也有name属性。方法的name属性返回紧跟在function关键字后面的函数名。如果是匿名函数,ES5环境会返回undefined,ES6环境会返回方法名
var obj = {
m1: function f() {},
m2: function () {}
};
obj.m1.name // "f"
obj.m2.name //ES5: undefined
obj.m2.name //ES6: "m2"
引用对象
如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量
var o1 = {};
var o2 = o1; o1.a = 1;
console.log(o2.a);//
o2.b = 2;
console.log(o1.b);//
如果取消某一个变量对于原对象的引用,不会影响到另一个变量
var o1 = {};
var o2 = o1; o1 = 1;
console.log(o2);//{}
实例方法
valueOf()
valueOf()方法返回当前对象
var o = new Object();
o.valueOf() === o // true
toString()
toString()方法返回当前对象对应的字符串形式
var o1 = new Object();
o1.toString() // "[object Object]" var o2 = {a:1};
o2.toString() // "[object Object]"
一般地,使用Object.prototype.toString()来获取对象的类属性,进行类型识别,详细情况移步至此
toLocaleString()
toLocaleString()方法并不做任何本地化自身的操作,它仅调用toString()方法并返回对应值
[注意]Date和Number类对toLocaleString()方法做了本地化定制
var o = {a:1};
o.toLocaleString() // "[object Object]"
判断为空
判断对象是否为空,有以下三种方法
1、for-in语句
let isEmpty = (obj) => {
for(let i in obj){
return false
}
return true
}
console.log(isEmpty({}))//true
console.log(isEmpty({a:}))//false
2、JSON.stringify方法
let isEmpty = (obj) => {
return JSON.stringify(obj) === '{}'
}
console.log(isEmpty({}))//true
console.log(isEmpty({a:}))//false
3、Object.keys方法
let isEmpty = (obj) => {
return !Object.keys(obj).length
}
console.log(isEmpty({}))//true
console.log(isEmpty({a:}))//false
参考资料
【1】 W3School-Javascript高级教程——引用类型 http://www.w3school.com.cn/js/pro_js_referencetypes.asp
【2】 阮一峰Javascript标准参考教程——对象 http://javascript.ruanyifeng.com/grammar/object.html
【3】《javascript权威指南(第6版)》第6章 对象
【4】《javascript高级程序设计(第3版)》第5章 引用类型
【5】《javascript语句精粹》第3章 对象
【6】《javascript面向对象精要》 第3章 理解对象
【7】《你不知道的javascript上卷》第3章 对象
深入理解javascript对象系列第一篇——初识对象的更多相关文章
- 深入理解javascript函数系列第一篇——函数概述
× 目录 [1]定义 [2]返回值 [3]调用 前面的话 函数对任何一门语言来说都是一个核心的概念.通过函数可以封装任意多条语句,而且可以在任何地方.任何时候调用执行.在javascript里,函数即 ...
- 深入理解javascript函数系列第一篇
前面的话 函数对任何一门语言来说都是核心的概念.通过函数可以封装任意多条语句,而且可以在任何地方.任何时候调用执行.在javascript里,函数即对象,程序可以随意操控它们.函数可以嵌套在其他函数中 ...
- 深入理解javascript作用域系列第一篇——内部原理
× 目录 [1]编译 [2]执行 [3]查询[4]嵌套[5]异常[6]原理 前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域 ...
- 深入理解javascript作用域系列第一篇
前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域貌似简单,实则复杂,由于作用域与this机制非常容易混淆,使得理解作用域的原 ...
- 深入理解javascript作用域系列第二篇——词法作用域和动态作用域
× 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极 ...
- 深入理解javascript作用域系列第二篇
前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极易出错.这实际上是由两种作用域工作 ...
- 深入理解javascript函数系列第二篇——函数参数
× 目录 [1]arguments [2]内部属性 [3]函数重载[4]参数传递 前面的话 javascript函数的参数与大多数其他语言的函数的参数有所不同.函数不介意传递进来多少个参数,也不在乎传 ...
- 深入理解ajax系列第一篇——XHR对象
× 目录 [1]创建对象 [2]发送请求 [3]接收响应[4]异步处理[5]实例演示 前面的话 ajax是asynchronous javascript and XML的简写,中文翻译是异步的java ...
- javascript面向对象系列第一篇——构造函数和原型对象
× 目录 [1]构造函数 [2]原型对象 [3]总结 前面的话 一般地,javascript使用构造函数和原型对象来进行面向对象编程,它们的表现与其他面向对象编程语言中的类相似又不同.本文将详细介绍如 ...
随机推荐
- 【DP】HDU 1260
HDU 1260 Tickets 题意:有N个人要买票,你可以一个一个人卖票,时间分别为Xs,也可以相邻两个人一起卖票,时间为Ys,从早上八点开始卖票,问你何时最早将N个人的票卖完. 思路:解决情况是 ...
- tomcat -ROOT 与webapps 的关系,关于部署的一些问题
现象:之前遇到很奇怪的问题,发完版之后没有效果,页面还是读取上一版的. 反复查找原因发现 http://localhost:8080/mobie 这个路径下的页面是正常的, 而 http://lo ...
- Log4Net异常日志记录在asp.net mvc3.0的应用
前言 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是简单的介绍如何在Visual ...
- Winform控件WebBrowser与JS脚本交互
1)在c#中调用js函数 如果要传值,则可以定义object[]数组. 具体方法如下例子: 首先在js中定义被c#调用的方法: function Messageaa(message) { ...
- poj2833
//poj2833优先队列.数据量太大,而且没有必要全部排序. //优先队列 //* #include<iterator> #include <stdio.h> #includ ...
- tomcat:域名指向项目名
把项目部署到tomcat目录webapps后,使用域名访问的时候域名后面需要加上项目名称,如果想直接输入域名就可以访问项目呢?看了下tomcat官方文档,我修改了tomcat安装目录下conf/ser ...
- C#程序代码分析(第三周)
刚开始看到这段程序,都不知道是什么东西,问过室友才知道是C#程序:但对C#一点都不了解,最基本的项目建设都不会,在室友的帮助下,以及在网上搜了一些资料,勉强算是完成了此次作业吧. using Syst ...
- SQLSERVER中的ALL、PERCENT、CUBE关键字、ROLLUP关键字和GROUPING函数
SQLSERVER中的ALL.PERCENT.CUBE关键字.ROLLUP关键字和GROUPING函数 先来创建一个测试表 USE [tempdb] GO )) GO INSERT INTO [#te ...
- 【Hello CC.NET】CC.NET 实现自动化集成
一.背景 公司的某一金融项目包含 12 个子系统,新需求一般按分支来开发,测完后合并到主干发布.开发团队需要同时维护开发环境.测试环境.模拟环境(主干).目前面临最大的两个问题: 1.子系统太多,每次 ...
- ASP.NET Core 源码阅读笔记(1) ---Microsoft.Extensions.DependencyInjection
这篇随笔主要记录一下ASP.NET Core团队实现默认的依赖注入容器的过程,我的理解可能并不是正确的. DependencyInjection这个项目不大,但却是整个ASP.NET Core的基础, ...