系统化学习前端之JavaScript(ES5)
前言
ES5 是 ECMAScript 的拓展,发布于 2009 年,目前大多数浏览器已支持,只有少部分不再维护低版本浏览器不支持,如 IE6 等。
ES5
ES5 是 ECMAScript 更新的 5.0 版本,更新内容多为代码规范与安全相关。
严格模式
严格模式是指对当前 js 文件规定一系列要求,不满足这些要求,js 文件执行会抛出错误。
严格模式要求:
-
禁止给未声明变量赋值。
-
禁止删除变量和函数。
-
禁止函数参数命名重复。
-
禁止使用八进制整型。
ES6 可以使用八进制整型,需要使用
0O
或者0o
作为前缀。 -
禁止使用
eval()
和with() {}
破坏作用域的方法。 -
禁止使用
arguments
和argumens.callee
。常规模式下,
arguments
是函数参数组成的类数组对象,argumens.callee
可以替换函数名。 -
禁止使用预留关键字命名变量。如 implements, interface, package, private, public, static, yield, let, package。
在 js 文件的开头添加 'use strict'
可以开启当前文件的严格模式。
this 关键字
var obj = {
name: 'jason',
getName: function () {
return this.name
}
}
对象方法中想要使用对象属性,可以使用 this
关键字替代对象,通常称:this
指向 obj
。由此类推,this
用作函数内,指向调用函数的对象。简而言之,this
谁调用指向谁。
-
不同函数的
this
指向-
普通函数
function fun() { console.log(this) // this 指向 window } fun()
注意:严格模式下,普通函数(包含匿名函数)的
this
指向undefined
。 -
构造函数
function Fun(name) { this.name = name console.log(this) // this 指向 obj } var obj = new Fun('jason')
-
原型方法
function Fun(name) { this.name = name } Fun.prototype.run = function() { console.log(this) // this 指向 obj } var obj = new Fun('jason') obj.run()
-
对象方法
var obj = { name: 'jason', getName: function () { console.log(this) // this 指向 obj } } obj.getName()
-
事件回调函数
var app = document.getElementById('app') function handleClick() { console.log(this) // this 指向 app } app.addEventListener('click', handleClick)
-
-
更改函数的
this
指向-
call
function sum(x, y) { console.log(this) // this 指向 由 window 更改为 obj return x + y } var obj = { name: 'jason' } sum.call(obj, 2, 3) // 5
-
apply
function sum(x, y) { console.log(this) // this 指向 由 window 更改为 obj return x + y } var obj = { name: 'jason' } sum.apply(obj, [2, 3]) // 5
-
bind
function sum(x, y) { console.log(this) // this 指向 由 window 更改为 obj return x + y } var obj = { name: 'jason' } var newSum = sum.bind(obj) newSum(2,3) // 5
-
注意:
call
,apply
,bind
为函数的方法。call
,apply
执行并调用函数,调用过程中改变this
指向,bind
执行返回新函数,返回的新函数改变了this
指向。
对象属性的特性
特性用于描述对象属性的特征,特性是为了实现 JavaScript 引擎使用的,JavaScript 中不能直接访问。根据特性不同,对象属性可以划分为数据属性和访问器属性。
-
数据属性
数据属性具有 4 个描述特征的特性:
-
Configurable
表示能否通过 delete 删除属性,或者能否修改属性的特性,或者能否把属性修改为访问器属性,默认特性值为 true。
-
Enumerable
表示能否通过 for-in 循环返回属性,默认特性值为 true。
-
Writable
表示能否修改属性的值,默认特性值为 true。
-
Value
属性的值,默认为 undefined。
var obj = { name: 'jason' }
字面量定义对象,
name
属性的Value
特性值为jason
,其他三个特性的特性值均为 true。Object.defineProperty()
可以修改属性的特性,接收三个参数,分别为对象,属性以及特性对象。var obj = { name: 'jason' } Object.defineProperty(obj, 'name', { value: 'jim' }) obj.name = 'jack' console.log(obj.name) // jim Object.defineProperty(obj, 'name', { configurable: false, // 一旦设置为 false,不可再修改为 true value: 'jim' }) delete obj.name // 严格模式 抛出错误 console.log(obj.name) // 常规模式 jim
-
-
访问器属性
字面量方法定义对象,对象属性为数据属性,无法定义对象属性为访问器属性,只能通过
Object.defineProperty()
定义。访问器属性的 4 个特性:-
Configurable
表示能否通过 delete 删除属性,或者能否修改属性的特性,或者能否把属性修改为数据属性,默认特性值为 true。
-
Enumerable
表示能否通过 for-in 循环返回属性,默认特性值为 true。
-
Get
在读取属性时调用的函数,默认值为 undefined。
-
Set
在写入属性时调用的函数,默认值为 undefined。
var obj = { name: 'jason', age: 20 } Object.defineProperty(obj, 'age', { get: function () { return this._age // _age 为 属性 age 的备份,防止在 set 过程中引发循环调用,导致栈溢出。 }, set: function (val) { this._age = val if(this._age > 20) { this.name = 'jim' } } }) obj.age = 21 console.log(obj.age) // 21 console.log(obj.name) // jim
通过
Object.defineProperty()
将obj
数据劫持,其属性改造为访问器属性,访问器属性可以做到修改单个属性,其他属性跟随变化的特点。注意:
set
或get
不设置会导致属性不可写或不可读。 -
-
批量设置数据属性和访问器属性
通过
Object.defineProperties()
可以批量设置属性为数据属性或者访问器属性,接收两个参数:对象以及属性对象。Object.defineProperties(obj, { name: { value: 'jason' }, age: { get: function () { return this._age }, set: function (val) { his._age = val } } }) obj.age = 21 console.log(obj) // {_age: 21, name: 'jason'} console.log(obj.age) // 21
-
查询属性特性
Object.getOwnPropertyDescriptor(obj, 'attr')
可以查询当前对象指定属性的特性设置,返回特性对象。Object.getOwnPropertyDescriptors(obj)
可以查询当前对象所有属性的特性设置,返回属性对象。
对象属性保护
对象的属性可以进行增删改查操作,因此对象是可变的。
-
增:obj.newAttr = val;
-
删:delete obj.attr;
-
改:obj.attr = val;
-
查:obj.attr;
两种方式可以保护对象的属性,防止篡改。
-
使用
Object.defineProperty()
修改属性的特性值,使其不可更改。Object.defineProperty(obj, 'attr', { configurable: false, writable: false, value: '' })
-
使用 Object 静态方法
-
Object.preventExtensions(obj);
防拓展,禁止增。其原理是将对象中的隐藏属性 extensible,由默认的 true 设置为 false。
注意:可以通过
Object.isExtensible(obj)
查看是否可拓展,返回 boolean 类型。 -
Object.seal(obj);
封闭,禁止增、删。其原理是将对象中的 extensible 设置 false,并将属性的特性 configurable 设置为 false。
注意:可以通过
Object.isSealed(obj)
查看是否封闭,返回 boolean 类型。 -
Object.freeze(obj);
冻结,禁止增、删、改。其原理是将对象中的 extensible 设置 false,并将属性的特性 configurable 和 writable 设置为 false。
注意:可以通过
Object.isFrozen(obj)
查看是否冻结,返回 boolean 类型。
-
原子继承
Object.create()
可以子对象继承父对象,同时为子对象添加数据属性或者访问器属性。
var father = {
eyes: 'black'
}
var child = Object.create(father, {
name: {
configurable: true,
enumerable: true,
writable: true,
value: 'jason',
},
age: {
get: function () {
return this._age
},
set: function (val) {
this._age = val
}
}
})
child.age = 21
console.log(child) // {name: 'jason', _age: 21}
console.log(child.eyes) // black
注意:
Object.setPrototypeOf()
接收两个参数,第一个参数为 child 对象,第二参数为 father 对象,等同于:chidl.__proto__ = father
,实现继承。
后记
当然 ES5 还新增了一些 string 和 array 的方法,在 ECMAScript 的内置对象中已经有所添加,可参考 ECMAScript。
本文来自博客园,作者:深巷酒,转载请注明原文链接:https://www.cnblogs.com/huangminghua/p/17272493.html