目录
1 原子继承 Object.create(prototype, [descriptors])
2 Object.defineProperty() 定义修改属性
3 获取原型 Object.getPrototypeOf(obj)
4 修改原型 Object.setPrototypeOf(obj,prototype)
1 Object.defineProperty(obj, prop, property) 设置单个属性特性
2 Object.defineProperties(obj, propsProperty)设置多个属性特性
3 Object.getOwnPropertyDescriptor(obj, prop) 查看属性特性
4 判断自身属性 obj.hasOwnProperty(prop)
5 获取属性名称Object.getOwnPropertyNames(obj)
一、JSON拓展
1 parse
将json字符串解析成js对象的
使用方式:parse(str, fn); str表示 处理的字符串
fn(属性名称,属性值 )执行函数 返回值表示这次处理的结果,this指向当前遍历的对象
是从叶子节点到根节点的方向遍历的,从外部向内部遍历的
2 stringify
将js对象转换成json字符串
使用方式:stringify(obj, fn) obj表示处理的对象
是从根节点到叶子节点的方向遍历的,从内部向外部遍历的
二 、 数组拓展
1 判断数组
第一种方式 判断对象类型是数组; Object.prototype.toString.call(obj) === '[object Array]'
第二种方式 判断构造函数是否是Array; obj.constructor === Array
第三种方式 判断是否是实例化对象; obj instanceof Array
第四种方式 判断数组的静态方法isArray; Array.isArray(obj)
2 数组索引值
arr.indexOf(成员) ;都是如果成员存在,返回索引值(大于等于0)如果成员不存在,返回-1
arr.lastIndexOf(成员): 都是全等查找
3 forEach
arr.forEach(function(item,index,arr ) {})成员值,索引值,原数组
返回值始终是undefined this 指向 window
与jq中each类似,区别是each执行函数的第一个参数是索引值,第二个参数是成员值
4 map
arr.map(function(item,index,arr ) {})
this 指向 window
map方法返回值是一个新数组,每一个成员就是每一次遍历成员时,执行函数的返回值
5 fill
arr.fill(填充成员); 填充数组方法 ,参数就是填充的成员,即使是函数也不会执行。 fill方法返回值是原数组
6 some
arr.some(function(item,index,arr ) {})
是数组的断言方法:判断数组中是否有些成员满足条件 有一个满足就返回true
7 evary
arr.every(function(item,index,arr ) {})
是数组的断言方法:判断数组成员是否全部满足条件 有一个不满足就返回false
8 filter
arr.filter(function(item,index,arr ) {})
返回值就是过滤的条件
filter方法返回值是由符合条件的成员组成的新数组
// 过滤数组
var result = arr.filter(function(item) {
// 返回数组成员长度等于3的
return item.length === 3;
})
9 reduce 与 reduceRight
传一个参:将从第二个成员遍历,第一个成员当成初始化的值
返回值就是当次累积的结果,会在下一次执行的时候,作为第一个参数传递
arr.reduce(function(pre, item, index, arr) {
//输出累加
return pre + item;
})
传两个参:将从第一个成员遍历,第二个参数就是初始化的值
返回值就是当次累积的结果,会在下一次执行的时候,作为第一个参数传递
arr.reduce(function(pre, item, index, arr) {
//输出 10 * 成员累乘
return pre * item;
}, 10)
三、函数绑定(bind)
<script>
function demo() {
console.log(this, arguments);
}
// 实现bind方法
Function.prototype.newBind = function(context) {
// 获取当前作用域的参数 即4, 5, 6
var arg = Array.prototype.slice.call(arguments, 1);
var fn = this;
return function() {
var args = Array.prototype.slice.call(arguments);
var all = arg.concat(args);
fn.apply(context, all);
}
}
var newFn = demo.newBind(document, 4, 5, 6);
// newfn就是:
// function() {
// var args = Array.prototype.slice.call(arguments);
// var all = [4,5,6].concat(args); //4,5,6,1,2,3
// demo.apply(context, all);
// }
newFn(1, 2, 3);
</script>
四、对象拓展
1 原子继承 Object.create(prototype, [descriptors])
ES5对对象拓展了一个静态方法,叫create,实现对对象的继承,返回值是一个对象,就是继承了参数对象的新对象,继承下来的属性以及方法是可以修改的
prototype 一个对象,作为新创建对象的原型,如果是null表示没有原型对象
descriptors一个对象值,可以包含若干个属性,属性名为新建对象的属性名,属性值为那个属性的属性描述符对象
// 定义一个对象
var obj = {
msg: 'hello',
num: 100,
color: 'red'
}
// obj的数据 会在新对象newObj的原型中使用
var newObj = Object.create(obj);
var newObj11= Object.create(obj, {
title: {
value: 'nihao',
// 不可枚举
enumerable: false
},
aaa: {
value: 'hello world'
}
})
console.log(newObj11);
五、日期拓展
toJSON
toJSON 将日期转化成json格式,(标准化格式)
它返回 UTC 时区的 ISO 格式日期字符串(由后缀 Z 表示)。
是ES5新增的方法,增强对日期格式的可读性。
var date = new Date();
// toJSON 将日期转化成json格式,(标准化格式)
// 返回的utc(世界标准时间)时间要加上8 才是北京时间
console.log(date.toJSON());
六、原型拓展
1 判断原型 Object.isPrototypeOf
Object.prototype.isPrototypeOf({}) // 该方法会查找整个原型链
2 Object.defineProperty() 定义修改属性
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
备注:应当直接在
Object
构造器对象上调用此方法,而不是在任意一个Object
类型的实例上调用。
//在Object的原型对象上 添加了name属性 值为王 不可改写
Object.defineProperty(Object.prototype, 'name', {
value: '王',
writable: false
})
3 获取原型 Object.getPrototypeOf(obj)
//返回值是obj的原型 即Object.prototype
Object.getPrototypeOf(obj);
//与__proto__等价
obj.__proto__ === Object.getPrototypeOf(obj)
4 修改原型 Object.setPrototypeOf(obj,prototype)
obj:要设置新的原型的对象
prototype: 要设置的新的原型 (可以是null可以是一个对象)
// 将obj的原型 改为null 他没有原型啦
Object.setPrototypeOf(obj, null);
//将obj的原型 改为构造函数People的原型了 继承原型(同一指向)
Object.setPrototypeOf(obj, People.prototype);
//修改obj的原型中的方法 People.prototype也被改变了
Object.getPrototypeOf(obj).getName = 123;
七、对象操作
对象有四个操作:增 删 改 查
1 对象禁拓 (不可增)
Object.preventExtensions(obj); 方法 该对象不能拓展属性(新增属性)操作是不可逆的
Object.isExtensible(obj); 查看是否禁拓; true没禁拓 false禁拓了
2 对象封闭(不可增删)
Object.seal(obj) 方法,不能对对象添加属性,删除属性,但是可以修改属性和查看属性
Object.isSealed(obj) true表示封闭了
3 对象冻结 (只能查看)
Object.freeze(obj) 方法,来冻结一个对象
Object.isFrozen(obj) true表示冻结了
八、 特性
1 Object.defineProperty(obj, prop, property) 设置单个属性特性
obj 表示对象
prop 表示对象的属性
property 表示属性的特性,是个对象
特性的作用就是用来说明属性。
特性对象有四个属性
value 表示属性的值
writable 属性是否可以修改,true: 可以修改 false:不能修改;obj.属性 = 值; 无效了
enumerable 表示属性是否可以被枚举 例如,是否可以通过for in遍历,true: 可以遍历 false: 不可遍历
configurable 表示属性是否可以再次被配置,(是否可以再次更改这些特性),true: 可以配置 false: 不能配置
通过字面量 添加的属性 其属性特性默认值为true; 通过defineProperty|defineProperties设置的 默认属性特性为false
特性对象有两个方法
get 获取属性的值;没有参数,作用域是这个对象,返回值就是这个属性的值
注意:绝对不能在该方法内部获取该属性,否则递归死循环
工作中,通常获取的是这个值的备用值
var obj = { _name: "xiaoming" } Object.defineProperty(obj, 'name',{ get: function() { return this._name; }, }); console.log(obj.name); //xiaoming obj.name = 'jack'; //不能修改 console.log(obj.name); //xiaoming
set 修改属性的值;参数就是修改的新的值,作用域是这个对象,返回值无意义
注意:绝对不能在该方法内部修改该属性,否则递归死循环
工作中,通常修改的是这个值的备用值
var obj = { _name: "xiaoming" } Object.defineProperty(obj, 'name',{ get: function() { return this._name; }, set: function(value) { this._name = value; } }); console.log(obj.name); //xiaoming obj.name = 'jack'; console.log(obj.name); //jack
2 Object.defineProperties(obj, propsProperty)设置多个属性特性
obj 表示原对象
propsProperty 表示属性特性对象
// 设置多个属性特性
Object.defineProperties(obj, {
msg: {
// 配置值
value: 'hello1',
// 不可修改
writable: false
},
num: {
// 配置值
value: 500,
// 不可枚举
enumerable: false
},
color: {
// 特性方法
get: function() {},
set: function() {}
}
})
3 Object.getOwnPropertyDescriptor(obj, prop) 查看属性特性
obj 表示这个对象
prop 表示这个属性
返回值是一个特性对象
Object.getOwnPropertyDescriptor(obj, 'msg')
4 判断自身属性 obj.hasOwnProperty(prop)
返回值: true: 表示自身属性 ;false: 表示原型属性
是判断自身有没这个属性 不在原型链上查找
5 获取属性名称Object.getOwnPropertyNames(obj)
返回值就是获取的所有属性,组成的数组
构造函数获取的属性名 是他的静态属性名
实例获取的是实例属性名 都不能获取原型上的属性名
九 、严格模式
进入严格模式非常简单,直接添加一行”use strict”字符串即可
高级浏览器识别它,会自动进入严格模式
低级浏览器不识别,只是当做一行简单的字符串处理
如果在js的第一行加入“use strict”此时,代码将处于“全局严格模式”
如果在某个函数的第一行加入“use strict”,当函数执行的时候,该函数将处于“局部严格模式”
(1)全局严格模式
定义变量不能省略 var,省略了var就抛出错误
(2)局部严格模式
在js中执行函数的时候,我们也可以进入严格模式,就是在函数开头添加”use strict”字符串,此时函数内部是严格模式的,函数外部就是正常
模式,只有当函数执行的时候,才能进入严格模式,函数外面仍然是正常模式,直到函数执行完毕,严格模式被解除。
(3)全局函数作用域
正常模式下,全局函数作用域是window,进入严格模式,全局函数作用域是undefined。以前正常模式下,在函数内部通过this修改数据会污染全局作用域,严格模式下会抛出错误,就不会污染全局作用域
(4)函数参数
正常模式下,函数可以定义同名参数,但是会产生覆盖问题,前面的参数被覆盖,严格模式下不允许定义同名的参数。
(5)对象属性
严格模式下,在通过对象字面量形式定义对象的时候,不允许定义同名的属性,定义同名的属性,前面的会被覆盖,目前还没有浏览器提示错误。
(6)delete关键字
只能用来删除对象的属性的,正常模式下,可以删除变量,函数等,但是没有删除成功
严格模式下,不允许去删除变量,函数等,只能删除对象的属性,否则会抛出错误。
(7)关键字、保留字、特殊变量
严格模式下不允许用关键字,保留字,特殊性变量来定义变量
关键字:具有一定功能的单词:var, function, for, while等
保留字:当前版本没有使用,将来某个版本将被使用的变量:class,public等等
特殊变量:在特定环境下具有一定功能的变量:arguments, eval等
在严格模式下,用这些单词定义变量会抛出错误
(8)8进制
js中以0开头的数字:如果后面的数字出现大于等于8的,就是10进制,如果后面的数字都小于8,就是8进制。所以容易出现混乱,所以严格模式下不允许使用8进制的数(数字不能以0开头),可以用0o 0O开头
console.log(0O11); //9 console.log(0o11); //9 console.log(0O11); //报错
(9)特殊字符
由于字符集的限制,有些字符,不能书写出来,可以通过特殊字符表达,例如\012表示一个换行,有时候为了避免字符冲突,我们也要转义,例如在单引号定义的字符串中,使用单引号。这样转义后,有的仍然是其自身,有的变成其他字符了,有歧义,因此严格模式不允许使用特殊字符。严格模式下可以使用转义字符,但是不能使用特殊字符
可以用用\n 不能 \012
(10)eval
eval可以将字符串作为语句去执行,但是会污染全局作用域。严格模式下,可以避免对全局作用域的污染。ES5对eval的处理是识别该特殊变量,并没有改变其功能,因此仍然想使用原有的功能,我们可以将eval赋值给一个变量,让后通过该变量去执行
(9)arguments.callee
在函数内部访问该函数:解决函数的执行时与函数名称耦合的问题(常用在递归中)。在浏览器渲染js的时候,并不是直接执行js语句,而是将js编译,执行编译的代码。但是由于arguments.callee无法被编译引擎编译优化,所以严格模式下不允许使用。js是动态语言,执行时候的作用域,因此在编译的时候js没有执行,因此arguments.callee到底哪个函数名称,编译引擎不知道,所以无法优化
(10)with
可以更改代码执行时候的作用域,严格模式下不能使用with,因为with无法让编译引擎编译优化。js 在编译的时候,无法执行with语句,也就是说,在with语句内部出现的变量,我们不知道是全局的还是更改的对象中的,因此有歧义,所以严格模式不允许使用