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

×

目录

[1]定义 [2]创建 [3]组成[4]引用

前面的话

  javascript中的难点是函数、对象和继承,前面已经介绍过函数系列。从本系列开始介绍对象部分,本文是该系列的第一篇——初识对象

对象定义

  javascript的基本数据类型包括undefinednullbooleanstringnumber和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));

【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);//1

  可以通过传入参数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

对象组成

  对象是属性的无序集合,由键名和属性值组成

【键名】

  对象的所有键名都是字符串,所以加不加引号都可以,如果不是字符串也会自动转换成字符串

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);//3

  如果属性值为函数,则通常把这个属性称为“方法”

var o = {
  p: function (x) {
    return 2 * x;
  }
};
o.p(1);//2

  由于对象的方法就是函数,因此也有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);// 1
o2.b = 2;
console.log(o1.b);// 2

  如果取消某一个变量对于原对象的引用,不会影响到另一个变量

var o1 = {};
var o2 = o1;

o1 = 1;
console.log(o2);//{}

参考资料

【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章 对象

时间: 2024-10-13 03:13:40

深入理解javascript对象系列第一篇——初识对象的相关文章

深入理解javascript作用域系列第一篇——内部原理

× 目录 [1]编译 [2]执行 [3]查询[4]嵌套[5]异常[6]原理 前面的话 javascript拥有一套设计良好的规则来存储变量,并且之后可以方便地找到这些变量,这套规则被称为作用域.作用域貌似简单,实则复杂,由于作用域与this机制非常容易混淆,使得理解作用域的原理更为重要.本文是深入理解javascript作用域系列的第一篇——内部原理 内部原理分成编译.执行.查询.嵌套和异常五个部分进行介绍,最后以一个实例过程对原理进行完整说明 编译 以var a = 2;为例,说明javasc

深入理解javascript作用域系列第二篇——词法作用域和动态作用域

× 目录 [1]词法 [2]动态 前面的话 大多数时候,我们对作用域产生混乱的主要原因是分不清楚应该按照函数位置的嵌套顺序,还是按照函数的调用顺序进行变量查找.再加上this机制的干扰,使得变量查找极易出错.这实际上是由两种作用域工作模型导致的,作用域分为词法作用域和动态作用域,分清这两种作用域模型就能够对变量查找过程有清晰的认识.本文是深入理解javascript作用域系列第二篇——词法作用域和动态作用域 词法作用域 第一篇介绍过,编译器的第一个工作阶段叫作分词,就是把由字符组成的字符串分解成

javascript面向对象系列第一篇——构造函数和原型对象

× 目录 [1]构造函数 [2]原型对象 [3]总结 前面的话 一般地,javascript使用构造函数和原型对象来进行面向对象编程,它们的表现与其他面向对象编程语言中的类相似又不同.本文将详细介绍如何用构造函数和原型对象来创建对象 构造函数 构造函数是用new创建对象时调用的函数,与普通唯一的区别是构造函数名应该首字母大写 function Person(){ this.age = 30; } var person1 = new Person(); console.log(person1.ag

深入理解this机制系列第一篇——this的4种绑定规则

× 目录 [1]默认绑定 [2]隐式绑定 [3]隐式丢失[4]显式绑定[5]new绑定[6]严格模式 前面的话 如果要问javascript中哪两个知识点容易混淆,作用域查询和this机制绝对名列前茅.前面的作用域系列已经详细介绍过作用域的知识.本系列开始将介绍javascript的另一大山脉——this机制.本文是该系列的第一篇——this的4种绑定规则 默认绑定 全局环境中,this默认绑定到window console.log(this === window);//true 函数独立调用时

javascript动画系列第一篇——模拟拖拽

× 目录 [1]原理介绍 [2]代码实现 [3]代码优化[4]拖拽冲突[5]IE兼容 前面的话 从本文开始,介绍javascript动画系列.javascript本身是具有原生拖放功能的,但是由于兼容性问题,以及功能实现的方式,用的不是很广泛.javascript动画广泛使用的还是模拟拖拽.本文将详细介绍该内容 原理介绍 模拟拖拽最终效果和在桌面上移动文件夹的效果类似 鼠标按下时,拖拽开始.鼠标移动时,被拖拽元素跟着鼠标一起移动.鼠标抬起时,拖拽结束 所以,拖拽的重点是确定被拖拽元素是如何移动的

javascript运动系列第一篇——运动函数

× 目录 [1]简单运动 [2]定时器管理 [3]分享到效果[4]移入移出[5]运动函数[6]透明度[7]多值[8]多物体 前面的话 除了拖拽以外,运动也是javascript动画的一个基本操作.通过CSS属性transition和animation可以实现运动.但是,要进行更精细地操作,javascript运动是必不可少的.本文将详细介绍javascript运动 简单运动 让一个元素在页面中运动起来很简单,设置定时器,改变定位元素的left或top值即可 <button id="btn&

深入理解javascript函数系列第三篇

前面的话 函数是javascript中特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本文是深入理解javascript函数系列第三篇--属性和方法 属性 [length属性] 函数系列第二篇中介绍过,arguments对象的length属性表示实参个数,而函数的length属性则表示形参个数 function add(x,y){ console.log(arguments.length)//3 console.log(

深入理解javascript作用域系列第五篇——一张图理解执行环境和作用域

× 目录 [1]图示 [2]概念 [3]说明[4]总结 前面的话 对于执行环境(execution context)和作用域(scope)并不容易区分,甚至很多人认为它们就是一回事,只是高程和犀牛书关于作用域的两种不同翻译而已.但实际上,它们并不相同,却相互纠缠在一起.本文先用一张图开宗明义,然后进行术语的简单解释,最后根据图示内容进行详细说明 图示 查看大图 概念 [作用域] 作用域是一套规则,用于确定在何处以及如何查找标识符.关于LHS查询和RHS查询详见作用域系列第一篇内部原理. 作用域分

深入理解javascript作用域系列第三篇

前面的话 一般认为,javascript代码在执行时是由上到下一行一行执行的.但实际上这并不完全正确,主要是因为声明提升的存在.本文是深入理解javascript作用域系列第三篇--声明提升(hoisting) 变量声明提升 a = 2 ; var a; console.log( a ); 直觉上,会认为是undefined,因为var a声明在a = 2;之后,可能变量被重新赋值了,因为会被赋予默认值undefined.但是,真正的输出结果是2 console.log( a ) ; var a