一.‘use strict’ 严格模式(区别)
(1)不使用var声明变量严格模式中将不通过,在循环中如果没有声明变量在非严格模式中很危险,i 会不小心溢出成为全局变量,但在严格模式中会报错,严格模式中变量必须显示声明(var/let/const)
(2)JS中作用域有两种,全局作用域和函数作用域。严格模式带来了第三种作用域:eval作用域,则任何使用'eval'的操作都会被禁止,(eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码,不常用容易报错),在严格模式下,arguments和eval是关键字,不能被修改,不能做变量处理
(3)with()被禁用:with 语句用于设置代码在特定对象中的作用域。with 语句是运行缓慢的代码块,尤其是在已设置了属性值时。大多数情况下,如果可能,最好避免使用它。
(4)caller/callee 被禁用
(5)对禁止扩展的对象添加新属性会报错:Object.preventExtensions(obj);然后对obj增加属性则会报错
(6)删除系统内置的属性会报错
(7)delete使用var声明的变量或挂在window上的变量报错
(8)delete不可删除属性(isSealed或isFrozen)的对象时报错(Object.isSealed() 方法判断一个对象是否被密封。Object.isFrozen()方法判断一个对象是否被冻结。)
(9)对一个对象的只读属性进行赋值将报错(Object.defineProperty(obj, 'a', {value: 1, writable: false})然后对obj属性修改则会报错)
(10)对象有重名的属性将报错
(11)函数有重名的参数将报错,在严格模式下,函数的形参也不可以同名
(12)八进制表示法被禁用
(13)arguments严格定义为参数,不再与形参绑定
(14)一般函数声明都在最顶层,ES5前的JS宽松,你可以写在if或for内(强烈鄙视这种写法)。当然Firefox的解析方式与其他浏览器不同,而在严格模式中这些写法将直接报错
(15)ES6里新增的关键字不能当做变量标示符使用,如implements, interface, let, package, private, protected, public, static, yield
(16)call/apply的第一个参数直接传入不包装为对象
(17)call/apply/bind的第一个参数为null/undefined时,this为null/undefined
二、json对象
JSON.stringify(obj/arr)
js对象(数组)转换为json对象(数组) JSON.parse(json)
json对象(数组)转换为js对象(数组)
三、object对象方法扩展
ES5给Object扩展了好一些静态方法, 常用的2个:
1.Object.create(prototype[, descriptors]) : 创建一个新的对象
1). 以指定对象(prototype)为原型创建新的对象
2). 指定新的属性, 并对属性进行描述
数据属性特性:value、writable、enumerable、configurable。
访问器属性特性:set、get、enumerable、configurable。
value:指定值
writable:标识当前属性值是否可以修改,默认为false
configurable:标识当前属性是否可以被删除,默认为false
enumerable:标识当前属性是否能用for in 枚举 默认为false
get : 用来得到当前属性值的回调函数
set : 用来监视当前属性值变化的回调函数
var human = {
info: 'human being'
};
var person = Object.create(human, {
name: {
configurable: false,
writable: true,
enumerable: true,
value: 'Scott'
},
gender: {
get: function() {
return "Male";
}
}
});
console.log(person);
上面代码相当于在human对象上进行扩展,添加了name和gender属性,进而创建一个新对象,我们来看一下person对象的结构: human的属性在
从打印信息中,我们可以看出,因为name属性是可遍历的,所以显示在Object{}中,当我们展开后,会看到gender的get方法,也可以看得到person的原型链,包含info属性的原型就是我们上面定义的human对象了,证明person对象确实是human对象的扩展。create与defineProperties有些相象之处,不同的是,create会创建一个新的对象,而defineProperties不会,我们也可以获取它的返回值,返回值就是原对象本身。
2.Object.defineProperties(object,descriptors)
作用:为指定object对象定义扩展多个属性
重要的事:非defineProperty定义的属性,四大特性默认值都是true。defineProperty添加的属性,四大特性默认值都是false。
get:用来获取当前属性值的回调函数
set:修改当前属性值的触发的回调函数,并且实参即为修改后的值
存取器属性:setter,getter一个用来存值一个用来取值
var obj2={firstName:"kobe",lastName:"bryant"};
Object.defineProperties(obj2,{
fullName:{
get:function () {//使用get来获取扩展属性的值
return this.firstName+" "+this.lastName//fullName想要设置的值
},
set:function (data) {//监听扩展属性,当扩展属性发生变化时自动调用后会将变化的值作为实参注入到set函数。
console.log("set()",data);
var names=data.split(" ");
this.firstName=names[0];
this.lastName=names[1];
}
}//创建一个配置对象
})
console.log(obj2.fullName)
obj2.fullName="haha heih";
console.log(obj2.fullName)
//get方法什么时候调用? 获取扩展属性值的时候,get方法自动调用
var objj={
age:15,
tall:180,
get all(){
return this.age+" "+this.tall;
},
set all(data){
console.log("set()",data);
var names=data.split(" ");
this.age=names[0];
this.tall=names[1];
}
}
console.log(objj);
objj.all="13 189";
console.log(objj);
其他的方法: 详细原文可看:https://blog.youkuaiyun.com/liuhe688/article/details/51001767
1.Object.defineProperty(object, propertyName, descriptor);defineProperty函数用于定义一个对象上的属性以及这个属性的描述符。
2.Object.getOwnPropertyDescriptor(object, propertyName);这个函数用于获取指定属性的描述符,其中会包括上面提到的一些描述符声明,我们直接看下面示例代码:
3.Object.getPrototypeOf(object);此函数用于获取指定对象的原型
4.Object.keys(object);此函数用于获取对象中可被遍历的全部属性的key的集合
5.Object.getOwnPropertyNames(object);此函数与keys函数相似,不过它会返回所有的键,包括哪些不可被遍历的属性。现在我们把keys函数替换成getOwnPropertyNames,看看结果如何:
6.Object.preventExtensions(object); & Object.isExtensible(object);preventExtensions函数用于禁止指定对象的扩展,即禁止向对象中添加新的属性。我们定义一个简单的对象,然后测试一下这个函数:
7.Object.seal(object); & Object.isSealed(object);
seal函数用于对指定对象进行封存,已封存的对象禁止再添加新的属性,禁止删除已有的属性,禁止重新定义已有属性的cnofigurable为true。来看下面一段代码:
8.Object.freeze(object); & Object.isFrozen(object);
freeze函数用于对指定对象进行冻结,冻结后的对象禁止添加属性,禁止删除属性,禁止更改属性,禁止使用defineProperty更改其configurable,writable,和enumerable的值。可以说freeze函数禁止对象属性上的所有操作,不过需要注意的是,如果对象的属性也是对象类型,那么这个属性对象下面的属性是不会被冻结的,我们依旧可以操作:
四、数组扩展
1.Array.prototype.indexOf(value):得到值在数组中的第一个下标,输入第一个3的下标
2.Array.prototype.lastIndexOf(value):得到值在数组中的最后一个下标
3.Array.prototype.forEach(function(item,index){}):遍历数组
4.Array.prototype.map(function(item,index){}):遍历数组返回一个新的数组,返回加工之后的值
5.Array.prototype.filter(function(item,index){}):遍历过滤出一个新的子数组,返回条件为true的值
1.indexOf
方法在字符串中自古就有
,string.indexOf(searchString, position)
。数组这里的indexOf
方法与之类似。
返回整数索引值,如果没有匹配(严格匹配),返回-1
. fromIndex
可选,表示从这个位置开始搜索,若缺省或格式不合要求,使用默认值0
,我在FireFox下测试,发现使用字符串数值也是可以的,例如"3"
和3
都可以。
2.lastIndexOf
方法与indexOf
方法类似:
array.lastIndexOf(searchElement[, fromIndex])
只是lastIndexOf
是从字符串的末尾开始查找,而不是从开头。还有一个不同就是fromIndex
的默认值是array.length - 1
而不是0
.
3.forEach
forEach
是Array新方法中最基本的一个,就是遍历,循环。它是遍历数组。
forEach方法里操作对象生效,想要操作里面的基本数据类型,就用arr[i]的形式直接操作数组。
例如下面这个例子:
[1, 2 ,3, 4].forEach(alert);
等同于下面这个传统的for
循环:
var array = [1, 2, 3, 4]; for (var k = 0, length = array.length; k < length; k++) { alert(array[k]); }
类似的$.each()
$.each( object, callback ):Object类型指定需要遍历的对象或数组;Function类型指定的用于循环执行的函数。参数object
可以是对象或数组。如果是对象,则遍历该对象的每个属性;如果是数组,则遍历该数组中的每个元素。
jQuery.each()
函数将根据每个成员(对象的属性或数组的元素)循环调用函数callback
。每次调用函数callback
时,jQuery.each()
函数都会将callback
函数内部的this
引用指向当前正在迭代的成员,并为其传入两个参数。第一个参数是当前迭代成员在对象或数组中的索引值(从0开始计数),第二个参数是当前迭代成员(与this
的引用相同)。
jQuery.each()
函数还会根据每次调用函数callback
的返回值来决定后续动作。如果返回值为false
,则停止循环(相当于普通循环中的break
);如果返回其他任何值,均表示继续执行下一个循环。
$(selector).each(function(index,element))
jQuery 遍历 - each() 方法主要用于DOM遍历,each() 方法规定为每个匹配元素规定运行的函数。
W3School上显示回调函数是必须的,index - 选择器的 index 位置,element - 当前的元素(也可使用 “this” 选择器)
4.map
array.map(
function
(currentValue,index,arr), thisValue)
.map() 通过指定函数调用一个数组中每一项元素,来创建一个新数组。 .map() 是一种 non-mutating(非变异) 方法,它创建一个新数组,而不是只对调用数组进行更改的 mutating(变异) 方法。这可能很难记住。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。
- currentValue:必须。当前元素的值
- index:可选。当期元素的索引值
- arr:可选。当期元素属于的数组对象
- thisValue:可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。可改变this指向,
5.筛选filter()
var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])
用法与map()相似
同样返回一个新数组(同样有一个可选的上下文参数)
不过是过滤掉“不合格”的元素
如果在回调函数中返回true,那么就留下来
返回false,就扔掉
var arr = [5, 20, 24, 66, 40, 49, 60];
var newArr = arr.filter(function(value){
return value % 10 == 0;
});
console.log(newArr); //[20, 40, 60]
五、bind()、call()、apply()的区别
call和apply绑定this 一个在后面传 一个要求放在数组里 bind返回的是一个函数要自己调用。
foo.call(obj,33); //直接传入参数
foo.apply(obj,[33]); //传入数据必须写在数组里
var obj={username:"kobe"};
function foo(data){
console.log(this,data)
}
// foo();
//自调用时this指向的是window,使this指向我们定义的obj
foo.call(obj);
foo.apply(obj);
//call和apply在不传参的情况下使用方式是一样的
//区别
function foo(data){
console.log(this,data)
}
foo.call(obj,33); //直接传入参数
foo.apply(obj,[33]); //传入数据必须写在数组里
//bind
var bar=foo.bind(obj,33);//绑定完this有一个返回值,不会立即调用当前函数而是将函数返回,通常用来指定回调函数的this。用bar来接收返回的函数然后执行
bar();
// 也可写成foo.bind(obj,33)()