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

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. 浅谈 Angular 项目实战

    为什么使用 Angular 我不是 Angular 的布道者,但如今痴迷 Angular,使用 Angular 做项目让我有一种兴奋感.目前的三大主流前端框架都研究过,博客中也有三者的相关教程,最早接 ...

  2. Python函数的装饰器修复技术(@wraps)

    @wraps 函数的装饰器修复技术,可使被装饰的函数在增加了新功能的前提下,不改变原函数名称,还继续使用原函数的注释内容: 方便了上下文环境中不去更改原来使用的函数地方的函数名: 使用方法 from ...

  3. CSS有哪些引入方式,link和@import的区别

    3种方式哦,行内样式.内部样式表.外部样式表 1. 行内样式又称为内联样式,直接在HTML标签的style属性中添加css. 会导致 HTML 代码变得冗长 2. 内部样式表又称为嵌入方式,是在HTM ...

  4. Xcode: Run Script 的运用, 使build打包后自动+1

    背景: 每次打包都要build+1处理,比较麻烦,使用 Run Script 的运用使build打包后自动+1 0. 使用xcode 添加run Script 然后就可以添加Run Script了 1 ...

  5. [Alpha阶段]第八次Scrum Meeting

    Scrum Meeting博客目录 [Alpha阶段]第八次Scrum Meeting 基本信息 名称 时间 地点 时长 第八次Scrum Meeting 19/04/12 新主楼F座2楼 35min ...

  6. 不能完整读取txt文件问题

    txt文件内容 5 1.3 0.4 3.4 -1.7 16.7 0.89 14.17 4.8 1.34 0.42 3.36 -2 16.2 0.9 14.8 4.9 1.30 0.37 3.51 -1 ...

  7. .Net上传图片的一些问题

    1.IIS上传文件大小限制和上传时间限制 异常详细信息: System.Web.HttpException: 超过了最大请求长度 打开iis找到部署的网站的配置编辑器 2.设置上传时间限制 3.设置上 ...

  8. pstree:command not found

    centos7默认并没有安装pstree,所以会有pstree:command not found yum -y install psmisc

  9. Spring Mybatis多数据源配置范例

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  10. 在Ubuntu 18.04系统上安装Systemback的方法(抄)

    在Ubuntu 18.04系统上安装Systemback的方法 2018-12-26 21:39:05作者:林莉稿源:云网牛站 本文介绍如何在Ubuntu 18.04或者Ubuntu 18.10系统上 ...