对象的属性名可加上引号,下面三行代码所定义的内容是完全相同的

var hero = { occupation : 1 };
var hero = { "occupation" : 1 };
var hero = { 'occupation' : 1 };

通常情况下不建议在属性名上加引号,但以下情境就必须加引号:

  • 属性名是JS的保留字之一
  • 属性名包含了除字母数字下划线$以外的字符
  • 属性名以数字开头

总而言之,若属性名不符合JS的变量命名规则就必须加上引号

对象的属性值可以是函数,因为函数本身也是一种数据,在这情况下,称该属性为对象的方法

var person = {
name : 'Sam',
say : function(){
alert('Hi~');
}
};

一些程序设计语言中,通常会有索引型数组(键名为数字)和关联型数组(通常以字符串为键值),也叫哈希表或字典

JS中用数组表示索引型数组,用对象表示关联型数组

访问对象的属性可用点号也可用中括号的方式,若访问的属性名不符合变量命名规则或属性名通过变量获取的,就必须使用中括号

对象属性名尽量别加引号,对象属性和方法的访问尽量使用点号

JS是动态类型语言,对象在任何时候都可进行增删改属性,但一些内建对象的一些属性不可改变如(Math.PI)

空对象本身会继承一些属性,ES5中才可以创建一个不继承任何属性的对象

当处于某个对象的方法内部时,可用this关键字访问该对象的属性或方法

JS程序所在的宿主环境一般都会为其提供一个全局对象,而所谓的全局变量不过是该对象的属性罢了

但宿主环境是Web浏览器时,它提供的全局对象是window,另一种获取全局对象的方法(此方法在浏览器外的大多数其他环境也同样有效)是在函数之外使用this关键字

创建对象时,实际同时赋予了该对象一种特殊的属性,即构造器属性,该属性实际上是一个指向用于创建该对象的构造器函数的引用

由于构造器属性所引用的是一个函数,因此我们也可以利用它来创建一个其他新对象

function Hero(name){
this.name = name;
}
var h = new Hero('Sam');
> h.constructor //ƒ Hero(name){this.name = name;}
var h2 = new h.constructor('May');
> h2.name //May

若对象是通过“对象文本标识法”(字面量形式)创建的,那实际上它就是由内建构造器Object()函数所创建

var obj = {};
> obj.constructor //function Object(){ [native code] }

通过instanceof操作符,可测试一个对象是否由某个指定的构造器函数创建

function Hero(){}
var h = new Hero()
var obj = {}
> h instanceof Hero //true
> h instanceof Object //true
> o instanceof Object //true

改变构造器的默认行为

function Fn(){
this.a = 1;
return {
b:2;
}
}
> var obj = new Fn()
> typeof obj.a //undefined
> obj.b //2

在这里,构造器返回的不再是包含属性a的this对象,而是另一个包含属性b的对象

但这也只有在函数返回值是一个对象时才会发生,若返回的是非对象类型时,该构造器会照常返回this

关于对象在构造器函数内如何创建出来,可设想在函数开头有个叫this的变量,这个变量会在函数结束时被返回,像这样

function C(){
// var this = {};
this.a = 1;
//return this;
}

对对象进行比较时,当且仅当两个引用指向同一个对象,结果才为true

JS中内建构造器(内建对象)大致可分为三类:

  • 数据封装类对象,Object、Array、Boolean、Number和String
  • 工具类对象,Math、Date、RegExp等
  • 错误类对象

不要去纠结什么是内建对象,什么是内建构造器,实际上它们是一回事,无论函数还是构造器函数,最后都是对象

Object是JS中所有对象的顶级父对象

var o = {};

var o = new Object();

是等价的

o.constructor :返回构造器函数的引用

o.toString : 返回对象的描述字符串

o.valueOf : 返回对象的单值描述信息,通常返回的就是对象本身

toString()方法会在需要用字符串来表示对象的时候被JS内部调用,如alert()或用+拼接时,该对象会调用自身的toString()方法

Array()是个用来构建数组的内建构造函数

var a = [];

var a = new Array();

是等价的

既然数组是由构造器创建,这意味着数组实际上也是对象,所以也继承了Object的所有方法和属性

可以手动设置数组的length属性,若设置的值大于当前数组长度,剩下的会被undefined自动填充,若小于则多出的部分会被移除



a.push("Hi")就相当于 a[a.length] = 'Hi',而 a.pop()则与

a.length--的结果相同。

函数是一种特殊的数据类型,实际上它也是对象,函数对象的内建构造器是Function(),此为创建函数的第三种方式但不推荐

函数的constructor属性也是其构造器函数的引用

length属性记录函数声明时参数列表里的参数个数

toString()方法返回的是该函数的源代码,用此方法查看那些内建函数的源码时,只会得到一个字符串[native code]

所以可用此来区分本地方法和自定义方法

JS中每个函数都会有call()和apply()两个方法,可让一个对象“借用”另一对象的方法,这也是种非常简单而实用的代码复用

var obj = {
job:'singer',
say:function (name) {
console.log('my name is ' + name +',I\'m a ' + this.job);
}
}
obj.say('Sam');
var obj2 = {
job:'teacher'
}
obj.say.call(obj2,'May');
obj.say.apply(obj2,['May']); //apply工作方式和call基本相同,唯一不同的是apply要传递数组

调用say()函数的对象方法call()时传递了两个参数,obj2对象和参数

这样一来,当say()被调用时,其中的this就被自动设置成obj2对象的引用

若没有传对象给call()的首参数或传递null,则调用对象将会被默认为全局对象

函数中的arguments是类似数组的对象,和数组的相似之处仅在于也包含了索引和length属性,而sort()、push()等数组方法却没有

但可把arguments转换成数组,这样就可使用各种各样的数组方法了

function f(){
var args = [].slice.call(arguments); //也可使用Array.prototype.slice来调用同一个函数
return args.reverse();
}
> f(1,2,3,4); //[4,3,2,1]

推断对象类型

数组的 typeof 返回值也为"object",那么如何区分对象与数组?

答案是使用 Object 对象的 toString()方法。这个方法会返回所创建对象的内部类名

> Object.prototype.toString.call({});
"[object Object]"
> Object.prototype.toString.call([]);
"[object Array]"

在这里,toString()方法必须要来自于 Object 构造器的 prototype 属性,直接调用Array 的 toString()方法是不行的,因为在 Array 对象中。这个方法已经出于其他目的被重写

这种推断方法也适用于DOM元素

> Object.prototype.toString.call(document.body); //"[object HTMLBodyElement]"

var b = new Boolean()

所创建的b是一个对象而不是基本数据类型的布尔值

Boolean()构造器创建的对象没有多少实用性,除了来自继承的,自身没有任何属性和方法

不使用new操作符而单独作为一般函数使用时,Boolean()可将一些非布尔值转换为布尔值(效果相当于两次取反操作)

创建的Number对象有三种方法,toFixed()、toPrecision()和toExponential()

var n = new Number(123.45);
n.toFixed(1);

在事先未创建Number对象的情况下也可使用这些方法,因为Number对象会在后台自动被创建和销毁

(1234).toExponential(); //"

Number对象自己的toString()方法可带一个参数表示用多少进制

b.toString(16)

基本类型的字符串不是对象,所以不含有任何属性和方法,但当我们将一个基本字符串当作对象使用时,后台会相应的创建String对象,在调用完后又把String对象立即销毁

> 'potato'.length // 6
> 'tomato'[0] // "t"

Math.random() 返回 [0,1) 间的某个数,若想获取min和max范围的值,可通过公式

((max - min) * Math.random()) + min

Math.round() 返回最靠近指定值的整数

内建构造器RegExp()来创建正则表达式对象

var reg = new RegExp('J.*t'); //匹配J开头,t结尾,中间包含一个或以上任意字符的字符串
var reg = /J.*t/; //字面量形式,正则文本标记法

正则表达式对象拥有的属性:

  • global:默认false,即找到第一个匹配时就停止
  • ignoreCase:是否区分大小写,默认false,区分
  • multiline:是否跨行搜索,默认false,不跨行
  • lastIndex:搜索开始的索引位,默认0
  • source:用于存储正则表达式匹配模式

    前三个属性可用regex修饰符表示,即g、i、m

    除了lastIndex,其他属性在对象创建后都不能再被修改
var reg = new RegExp('J.*t','gmi'); //修饰符无序,传递给构造器后相应的属性就被设为true
var reg = /'J.*t'/gi;

RegExp对象有两种可用于查找匹配内容的方法:test()和exec()

test()返回布尔值

exec()返回数组,匹配的字符串组成的数组

/j.*t/i.exec('Javascript')[0]; //"Javascript"

String对象的IndexOf()和lastIndexOf()方法只能用于纯字符串式子的搜索,若想获得更强大的文本搜索能力就需要使用正则表达式

但String对象也有此能力

String对象的这些方法都能以正则作为参数

match():返回数组,包含匹配内容的数组

search():返回索引,第一个匹配内容所在的索引

replace():将匹配内容替换成指定字符串

split():返回数组,根据字符串或正则,将字符串切割成数组

这四个方法不但能接收正则,也包括字符串,它们会把接收到的字符串参数自动转换成regex对象,就像我们直接传递new RegExp()一样

"test".replace('t', 'r');
"test".replace(new RegExp('t'), 'r'); //两者等价

使用字符串的话就不能使用修饰符igm,而且replace()中global修饰符的值将为false,也就是只有第一个匹配的字符串才会被替换,剩下的不会

若正则表达式中分了组(即带括号),则可用$1表示匹配分组的第一组,$2表示第二组,以此类推

var email = 'Jay@qq.com';
var name = email.replace(/(.*)@.*/,'$1');
> name; //Jay

回调式替换

通过回调,可在替换操作之前实现一些处理逻辑

function replaceCallback(str){
console.log(arguments); //若arguments赋值给一个全局变量,这就能得到replace()传来的参数
return "_" + str.toLowerCase(); //而return的值又会作为替换值
}
var s = 'JavaScript';
s.replace(/(J)(a)/g, replaceCallback);



在这里,回调接收到的参数实际有四个

首参数是正则匹配到的内容,尾参数是被搜索的字符串,尾参数之前的一个参数是所匹配内容的索引

剩下的参数则是各个分组

str是形参,replace()函数内部传给replaceCallback函数的参数是实参

Error

程序出现错误时,会抛出一个Error对象,该对象可能由以下几个内建构造器中的一个产生

它们包括EvalError、RangeError、ReferenceError、SyntaxError、TypeError和URIError等,所有这些构造器都继承自Error对象

错误捕获很容易,只需要使用 try 语句后接一个 catch 语句即可

try(){
iDontExist(); //iDontExist()是个未定义的函数
} catch (e){
//这里写修复错误的代码或将错误进行反馈
}

try 语句及其代码块

catch 语句及其参数变量和代码块

catch 语句的参数 e 实际上是一个 Error 对象,跟其他对象一样,它也

提供一系列有用的方法与属性。遗憾的是,不同的浏览器对于这些方法与属性都有着各自

不同的实现,但其中有两个属性的实现还是基本相同的,那就是 e.name 和 e.message

e.name 是构造当前 Error 对象的构造器名称

也可以用 new Error()或者其他 Error 对象构造器来自定义一个 Error 对象,然后告诉 JS 引擎某个特定的条件,并使用 throw 语句来抛出该对象

try {
var total = maybeExists();
if (total === 0) {
throw new Error('Division by zero!');
} else {
alert(50 / total);
}
} catch (e){
alert(e.name + ': ' + e.message);
} finally {
alert('Finally!'); //finally是可选的,无论错误是否发生,这里的代码都会执行
}

这里抛出的是一般性的错误提示,使用的是 throw new Error('Division by zero!')语句

也可以根据自身的需要来明确错误类型,例如可以利用 throw new RangeError('Division by zero!')语句来抛出该错误

或者不用任何构造器,直接定义一个一般对象抛出:

throw {
name: "MyError",
message: "OMG! Something terrible has happened"
}

这样一来,就可以使用自定义的 Error 名,从而解决了浏览器之间由于抛出错误不相同所导致的问题

五种基本数据类型,除了 undefined 和 null 外,其他三个都有相应的构造器 函数

分别是 Number()、String()以及 Boolean(),通过它们我们可以创建出相应的对象,通过将这些基本类型封装成对象,我们就可以在其中集成一些有用的工作方法

Number()、String()以及 Boolean()的调用可分为两种形式:

  • 使用 new 操作符调用 — 用于新建对象。
  • 不使用 new 操作符调用 — 用于将任意值转换成基本数据类型

「JavaScript面向对象编程指南」对象的更多相关文章

  1. 「JavaScript面向对象编程指南」基础

    DOM标准是独立的(即并不依赖JS)操作结构化文档的方式 BOM实际是个与浏览器有关的对象集合,原来没任何标准可言,H5诞生后才被定义了一些浏览器间通用的对象标准 ES5严格模式"use s ...

  2. 「JavaScript面向对象编程指南」原型

    在 JS 中,函数本身也是一个包含了方法(如apply和call)和属性(如length和constructor)的对象,而prototype也是函数对象的一个属性 function f(){} f. ...

  3. 「JavaScript面向对象编程指南」闭包

    闭包 JS只有函数作用域,函数外为全局变量,函数内为局部变量 绿圆是函数fn的作用域,在这范围内可访问局部变量b和全局变量a,橙圆是fn内部函数inner的作用域,此范围内可访问自身作用域内的变量c, ...

  4. JavaScript面向对象编程指南(四) 对象

    第4章 对象 4.1 从数组到对象 对象的组成:变量名.{}.用逗号分割的属性.用冒号分割的键/值对. var f={ name:'alen', // 可以在属性名上加引号 age:12 }; 对象文 ...

  5. 《JavaScript面向对象编程指南(第2版)》读书笔记(一)

    目录 一.对象 1.1 获取属性值的方式 1.2 获取动态生成的属性的值 二.数组 2.1 检测是否为数组 2.2 增加数组长度导致未赋值的位置为undefined 2.3 用闭包实现简易迭代器 三. ...

  6. 《JavaScript面向对象编程指南(第2版)》读书笔记(二)

    <JavaScript面向对象编程指南(第2版)>读书笔记(一) <JavaScript面向对象编程指南(第2版)>读书笔记(二) 目录 一.基本类型 1.1 字符串 1.2 ...

  7. 《JavaScript面向对象编程指南》读书笔记②

    概述 <JavaScript面向对象编程指南>读书笔记① 这里只记录一下我看JavaScript面向对象编程指南记录下的一些东西.那些简单的知识我没有记录,我只记录几个容易遗漏的或者精彩的 ...

  8. 《JavaScript面向对象编程指南》读书笔记①

    概述 JavaScript快忘完了,想看一本专业书拾遗,所以看了这本<JavaScript面向对象编程指南>. 个人觉得这本书讲的很透彻很易懂,一些原来有疑惑的地方在这本书里面豁然开朗,看 ...

  9. 闭包初体验 -《JavaScript面向对象编程指南》

    下面是我对闭包的理解:(把他们整理出来,整理的过程也是在梳理) 参考<JavaScript面向对象编程指南> 1.首先,在理解闭包之前: 我们首先应该清楚下作用域和作用域链 作用域:每个函 ...

随机推荐

  1. 什么是Vagrant

    相信大家对VMware和VirsualBox不会太陌生,虚拟化的好处在这里我就不多说了.那么我们就一起来学习用Vagrant 为自己来打造一个神奇的跨平台开发环境吧!! 开发过程中,我们经常碰到一个问 ...

  2. js数组中随机选取一个数值!!

    var arr = ["太阳光大","成功是优点的发挥","不要小看自己", "口说好话","手心向下是助人& ...

  3. 收藏了8年的PHP优秀资源,都给你整理好了

    https://segmentfault.com/a/1190000018071558 最后更新于 2019.02.12 以下是我整理好的 PHP 资源,各位看官拿去用,不用再自己找了. 每周在 Gi ...

  4. A Base Class pointer can point to a derived class object. Why is the vice-versa not true?

    问题转载自:https://stackoverflow.com/questions/4937180/a-base-class-pointer-can-point-to-a-derived-class- ...

  5. 缓存,热点key

    热点Key问题的发现与解决 https://help.aliyun.com/document_detail/67252.html 缓存击穿.失效以及热点key问题 https://www.jiansh ...

  6. linux 系统工具图

  7. docker-lnmp dockerfile

    code: FROM php:7.1.26-fpm WORKDIR /usr/share/nginx/html # bcmath pdo_mysql intl gd zip opcache xdebu ...

  8. 【linux】工作中linux系统常用命令操作整理

    1.Linux如何查看端口 使用lsof(list open files)命令,lsof -i:端口号 用于查看某一端口的占用情况,比如查看8000端口使用情况,lsof -i:8000. 或者使用n ...

  9. Java 8 特性 —— 方法引用

    方法引用通过方法的名字来指向一个方法.方法引用可以使语言的构造更紧凑简洁,减少冗余代码.方法引用使用一对冒号 :: .下面,我们在 Car 类中定义了 4 个方法作为例子来区分 Java 中 4 种不 ...

  10. The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored E.Sequence in the Pocket(思维题)

    传送门 题意: 给出一个序列,你可以将任意一个数移到最前面: 求最少需要移动多少次,可以是此序列变成非递减序列: 思路: 定义 (ai,aj) 为逆序对 ( i < j , ai > aj ...