ES5

1 JSON–parse

将json字符串解析成js对象
使用方式:parse(str, fn)
str 处理的字符串
fn 回调函数
返回值表示这次处理的结果
第一个参数表示属性名称
第二个参数表示属性值
this指向当前遍历的对象
是从叶子节点到根节点的方向遍历的,从外部向内部遍历

var str = '{"a": 1, "b": "2", "c": { "d": 4 }}';
// 从叶子节点到根节点方向遍历的,由内到外遍历的
// 解析成对象,转换的过程中加一个函数,可以对里面的属性做处理
var obj = JSON.parse(str, function(key, value) {
    // console.log(arguments, this);
    if (typeof value === 'string') {
        // return parseInt(value);
        return +value;
    }
    return value;
});
console.log(obj);

2 JSON–stringify

将js对象转换成json字符串
使用方式:stringify(obj, fn)
obj 处理的对象
fn 回调函数
返回值表示这次处理的结果
第一个参数表示属性名称
第二个参数表示属性值
this指向当前遍历的对象
是从根节点到叶子节点的方向遍历的,从内部向外部遍历

        var obj = {
            a: 1,
            b: "2",
            c: {
                d: 4
            }
        }
        // 遍历的顺序,由根节点到叶子节点方向遍历的
        var str = JSON.stringify(obj, function(key, value) {
            if (typeof value === 'string') {
                return +value;
            }
            return value;
        });
        console.log(str);

3 判断数组

第一种方式 判断对象类型是数组
	Object.prototype.toString.call(obj)
第二种方式 判断构造函数是否是Array
	obj.constructor=== Array
第三种方式 判断是否是实例化对象
	obj instanceof Array
第四种方式 判断数组的静态方法isArray	es5新增静态方法
	Array.isArray(obj)

4 数组–获取数组的索引值

ES5为数组扩展了两个方法:indexOf, lastIndexOf来获取数组成员的索引值
参数就是这个成员
返回值就是索引值
如果成员存在,返回索引值(大于等于0)
如果成员不存在,返回-1
查找成员的时候,不会做数据类型的转换,是真正的全等查找
indexOf是从前往后查找
lastIndexOf是从后向前查找的

var arr = [1, '2', 2, 3, 2, 5, 2, 4, 2, 6, 7];
// var result = arr.indexOf(2);
var result = arr.lastIndexOf(2);
console.log(result);

5 数组–forEach

作用:用来代替for循环,遍历数组,是数组遍历器方法,并没有移出循环,而是将循环封装在遍历器方法forEach的内部
参数是回调函数
回调函数有三个参数:成员值,索引值,原数组
this指向window
返回值对forEach方法执行结果无影响
forEach方法返回值始终是undefined
jQuery提供了另一个类似方法,叫each,区别是each回调函数的第一个参数是索引值,第二个参数是成员值

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var result = arr.forEach(function(item, index, arr) {
	console.log(item, index, arr);
})
console.log(result);	//返回值始终是undefined

6 数组–map

作用:遍历数组并映射结果,与forEach非常类似,区别是它的返回值有意义
参数是回调函数
三个参数:成员值,索引值,原数组
this指向window
返回值是map方法执行的结果数组的成员
map方法返回值是一个新数组,每一个成员就是每一次遍历成员时,回调函数的返回值

 var arr = ['hello', 'world', 'console', 'log', 'print'];
 // 返回第一个字母
 // 映射一个新数组
 var result = arr.map(function(item, index, arr) {
 	return item[0];
 })
 console.log(result);

// 实现map方法
if (!Array.prototype.map) {
    Array.prototype.map = function(callBack) {
        var result = []
        for (var i = 0; i < this.length; i++) {
        	result.push(callBack(this[i], i, this));
        }
        return result;
    }
}

7 数组–fill

填充数组方法
作用:我们通过new Array(len),或者Array(len)创建的数组只有长度,没有成员,所以我们不能用迭代器方法(如forEach,map等等)遍历,为了遍历数组,我们可以向数组中填充成员
参数就是填充的成员,即使是函数也不会执行
fill方法返回值是原数组

        var arr = new Array(5);
        // 填充成员
        arr.fill(1);
        console.log(arr);

        // 实现fill
        if (!Array.prototype.fill) {
            Array.prototype.fill = function(item) {
                for (var i = 0; i < this.length; i++) {
                    this[i] = item;
                }
                return this;
            }
        }

8 数组–filter

实现对数组的过滤
使用方式跟forEach一样
参数是回调函数,回调函数有三个参数:成员值,索引值,原数组
返回值就是过滤的条件
filter方法返回值是由符合条件的成员组成的新数组

        // filter
        var arr = ['hello', 'world', 'console', 'log', 'print'];
        // var result = arr.filter(function(item, index, arr) {
        //     return item.indexOf('h') >= 0;
        // })
        // console.log(result);



        // 实现filter
        if (!Array.prototype.filter) {
            Array.prototype.filter = function(callBack) {
                var result = [];
                for (var i = 0; i < this.length; i++) {
                    if (callBack(this[i], i, this)) {
                        result.push(this[i]);
                    }
                    
                }
                return result;
            }
        }

9 数组–some

是数组的断言方法:判断数组中是否有些成员满足条件
使用方法跟forEach一样,参数是回调函数
回调函数有三个参数:成员值,索引值,原数组
返回值是判断的依据
some方法返回值
true:至少有一个满足条件
false:一个条件都不满足
some对true敏感,遇到一个满足条件的成员,就停止执行

        var arr = ['hello', 'world', 'console', 'log', 'print'];

        // some

        var result = arr.some(function(item, index, arr) {
            return item.indexOf('w') >= 0;
        })
        console.log(result);

        // 实现some方法
        if (!Array.prototype.some) {
            Array.prototype.some = function(callBack) {
                for (var i = 0; i < this.length; i++) {
                    if (callBack(this[i], i, this)) {
                        return true;
                    }
                    
                }
                return false;
            }
        }
        var result = arr.some(function(item, index, arr) {
            return item.indexOf('e') > 0;
        })
        console.log(result);

10 数组–every

是数组的断言方法:判断数组中所有成员,是否都满足条件
使用方法跟forEach一样,参数是回调函数
回调函数有三个参数:成员值,索引值,原数组
返回值是判断的依据
every方法返回值
true:全部成员都满足条件
false:至少有一个成员不满足条件
every对false敏感,遇到一个不满足条件的成员,就停止遍历

        // every
        var arr = ['hello', 'world', 'console', 'log', 'print'];
        // var result = arr.every(function(item, index, arr) {
        //     return item.length > 2;
        // })
        // console.log(result);


        // 实现every
        if(!Array.prototype.every) {
            Array.prototype.every = function(callBack) {
                for (var i = 0; i < this.length; i++) {
                    if (!callBack(this[i], i, this)) {
                        return false;
                    }
                }
                return true;
            }
        }
        var result = arr.every(function(item, index, arr) {
            return item.length > 3;
        })
        console.log(result);

11 数组–reduce与reduceRight

这两个是累加方法,reduce是从前向后累加,reduceRight是从后向前累加
对所有的成员逐一处理,并将结果返回
参数是回调函数
四个参数:上一次累加的结果,当前成员值,当前索引值,原数组
返回值就是当前累积的结果,会在下一次执行的时候,作为第一个参数传递
reduce是从第二个成员开始遍历,第一个成员将在第一次遍历的时候作为第一个参数
注意:如果reduce方法传递了第二个参数,将从第一个成员遍历,第二个参数就是初始化的值
reduceRight是从倒数第二个成员开始遍历,倒数第一个成员在第一次遍历的时候作为第一个参数
注意:如果reduceRight方法传递了第二个参数,将从倒数第一个成员遍历,第二个参数就是初始化的值

        var arr = [2, 4, 6, 8, 10];
        // var result = arr.reduce(function(res, item) {
        //     return res + item;
        // }, 0)
        // console.log(result);



        var result = arr.reduceRight(function(res, item) {
            return res + item;
        }, 0)
        console.log(result);

12 函数扩展–函数绑定

ES5对函数扩展了bind方法
作用:为函数绑定作用域(当函数执行的时候,改变函数的作用域,并传递参数)
目前为止改变this指向的方法|关键字:bind, call, apply, with, eval
call与apply的区别
他们都是改变函数this指向的方法,都是在调用该方法的时候,执行函数并改变作用域的,第一个参数都是改变的this指向
call从第二个参数开始,表示传递给函数的参数
apply第二个参数是数组,每一个成员表示传递给函数的参数
bind跟call类似
第一个参数表示改变的this指向
从第二个参数开始,表示传递的参数
区别:
call和apply调用即执行
bind调用不执行,但是得到一个新的方法,是可以执行的方法
bind方法实现也是通过apply实现的

bind通过两项技术实现的
1 函数绑定:函数作为参数传递的同时,可以改变函数的this指向
作用:改变this指向
2 函数柯里化:一个接收多个参数的函数,我们一个一个的传递参数,在函数执行的时候,传递剩余的参数并得到结果
作用:增强了函数的适用性
跟函数的重载有点像
函数的重载是在函数内部实现的
函数柯里化是在函数外部实现的(没有修改函数内部结构类似于装饰者模式,是对函数的包装)

<script>
    function demo() {
        console.log(this, arguments);
    }
    var obj = {
        color: 'red'
    }
    // 更改this指向,函数执行了
    // 返回值都是undefined
    // demo.call(obj, 1, 2, 3);
    // demo.apply(obj, [1, 2, 3]);

    //     // 改变this指向,不让函数执行
    //     var fn = demo.bind(obj, 1, 2, 3);
    //     // 执行fn
    //     fn(4, 5, 6);

    // 绑定事件
    // btn.onclick = demo;
    // 让this指向obj
    // btn.onclick = demo.call(obj, 1, 2, 3);   会立即执行,绑定不了事件
    // btn.onclick = function(e) {
    //     demo.call(obj, e);
    // }


    // es5中,可以使用bind解决这个问题
    // btn.onclick = demo.bind(obj, 1, 2, 3);

    // bind方法通过两项技术实现:函数绑定,函数柯里化
    
    /***
    *函数绑定:让函数作为参数传递,当函数执行的时候,更改其this指向
    *@fn       执行的参数
    *@context  上下文对象
    ***/ 
    function bind(fn, context) {
        // 返回函数
        return function() {
            // 执行该函数相当于执行fn
            // 更改this指向,并且传递参数
            fn.apply(context, arguments)
        }
    }
    // btn.onclick = bind(demo, obj);


    /***
     * 函数柯里化,一个接收多个参数的函数,我们一个一个的传递参数,在函数执行的时候,传递剩余的参数并得到结果(增强了函数的适用性),
     * @fn      表示函数
     * 从第二个参数开始,表示传递的参数
     * ***/
    function curry(fn) {
        // 获取参数
        var args = Array.prototype.slice.call(arguments, 1);
        // 返回一个新函数
        return function() {
            // 将参数转化成数组
            var arr = Array.prototype.slice.call(arguments);
            // 合并参数
            var all = [].concat(arr, args);
            // 执行原来的函数,传递剩余的参数(新函数的参数)
            return fn.apply(null, all);
        }
    }


    

    function add(num1, num2) {
        return num1 + num2;
    }



    // function add(num1, num2) {
    //     // 参数重载:根据参数的不同,做不同的处理
    //     if (num2 !== undefined) {
    //         return num1 + num2;
    //     } else {
    //         return num1 + 10;
    //     }
    // }


    // var add10 = curry(add, 10);
    // console.log(add10(5));



    /****
     * 函数绑定的实现,综合使用函数绑定以及函数柯里化技术
     * 
     * 
     * 
     * *****/ 
    Function.prototype.icktBind = function(context) {
        // 获取剩余的参数
        var args = Array.prototype.slice.call(arguments, 1);
        // 缓存this实例:就是方法
        var fn = this;
        return function() {
            var arr = Array.prototype.slice.call(arguments);
            var all = [].concat(arr, args);
            // 执行函数,更改this指向,并传递参数
            return fn.apply(context, all);
        }
    }
</script>

13 对象扩展–原子继承

ES5对对象扩展了一个静态方法,叫create,实现对对象的继承
是对寄生式继承的一个扩展,就是继承了参数对象的新对象
继承下来的属性以及方法是可以修改的

        // 针对对象的继承
        var book = {
            title: 'books',
            price: 34,
            getTitle: function() {
                return this.title;
            }
        }

        // 继承对象
        var book2 = Object.create(book, {
            // 构造函数
            constructor: {
                value: Array
            }
        })
        // console.log(book, book2); 
        // console.log(book2.getTitle());


        // 实现create方法
        function create(obj, props) {
            // 定义寄生类
            function F() {};
            // 更改原型
            F.prototype = obj;
            // ES5中的Object.create方法本质上是通过特性实现继承的
            // 重写继承的属性
            if (props) {
                for (let key in props) {
                    F.prototype[key] = props[key];
                }
            }
            // 返回实例,寄生工厂模式
            return new F();
        }

14 日期扩展–toJSON

toJSON将日期转化成json格式(标准化格式)
它返回UTC时区的ISO格式日期字符串(由后缀Z表示)
是ES5新增的方法,增强对日期格式的可读性

15 严格模式

ES5新增了严格模式,可以使我们写的代码更加的安全可靠
进入严格模式:直接添加一行"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开头)

9 特殊字符
严格模式下可以使用转义字符,不能使用特殊字符
特殊字符 var str = ‘hello\012world’
转义字符 var str = ‘hello’world’ var str = ‘hello\nword’

10 eval
eval可以将字符串作为语句去执行,但是会污染全局作用域。严格模式下,可以避免对全局作用域的污染。ES5对eval的处理是识别该特殊变量,并没有改变其功能,因此仍然想使用原有的功能,我们可以将eval赋值给一个变量,然后通过该变量去执行

11 arguments.callee
在函数内部访问该函数:解决函数执行时与函数名称耦合的问题(常用在递归中)。由于arguments.callee无法被编译引擎编译优化,所以严格模式下不允许使用
function add(num) {
if (num <= 1) {
return num;
}
// return num + add(num - 1);
//解决函数执行时与函数名称耦合的问题,使用arguments.callee
return num + arguments.callee(num - 1);
}

12 with
可以更改代码执行时候的this指向,严格模式下不能使用with,因为with无法让编译引擎编译优化
避免每次访问Math
with(Math) {
console.log(PI);
consoloe.log(abs(-5));
console.log(random());
}

16 特性

对象是什么,我们用属性来说明
属性是什么,我们用特性来说明
特性的作用就是用来说明属性
定义特性
Object.defineProperty(obj, prop, property)
obj 表示对象
prop 表示对象的属性
property 表示属性的特征,是个对象

        // 定义对象
        var obj = {
            num: 100
        }
        // 添加属性
        Object.defineProperty(obj, 'color', {
            value: 'red',
            // 是否能够被修改
            writable: true,
            // 是否可以遍历
            enumerable: true,
            // 是否可以被配置
            configurable: true
        })
        // 特性方法
        Object.defineProperty(obj, 'msg', {
            // 特性方法
            // 取值器方法(获取)
            get: function() {
                // return 'hello'
                console.log(this, arguments);
            },
            // value和writable不能与get和set一起定义
            // 赋值器方法(修改)
            set: function() {
                console.log(this, arguments);
            }
        })

        
        // 修改属性
        obj.color = 'green';
        obj.msg = 'green';


        console.log(obj);
        console.log(obj.msg);
四个属性

特性对象有四个属性
value 表示属性的值

writable		表示属性是否可以修改
	true:可以修改   false:不能修改

enumerable 表示属性是否可以被枚举 例如,是否可以通过for in遍历
true:可以遍历 false:不可遍历

configurable 表示属性是否可以再次被配置(是否可以再次更改这些特性)
true:可以配置 false:不能配置

除了value,其余都是布尔值

特性方法

特性对象有两个方法,注意:这两个方法不能与value和writable兼容
get 获取属性的值
没有参数,this指向这个对象,返回值就是这个属性的值
注意:绝对不能在该方法内部获取该属性,否则递归死循环
工作中,通常获取的是这个值的备用值
set 修改属性的值
参数就是修改的新的值,this指向这个对象,返回值无意义
注意:绝对不能在该方法内部修改该属性,否则递归死循环
工作中,通常修改的是这个值的备用值

定义多个属性特性
Object.defineProperties(obj, propsProperty)
	obj				表示原对象
	propsProperty	表示属性特性对象
		key		表示属性名称
		value	就是特性对象
判断自身属性

for in循环可以遍历对象的自身属性以及原型属性,有时候需要遍历自身属性,不希望遍历原型方法,我们可以使用hasOwnProperty方法
obj.hasOwnProperty(prop)
对象调用
参数就是这个属性
返回值
true:表示自身属性
false:表示原型属性

获取属性名称

有时我们只想获取所有自身属性名称可以使用Object.getOwnpropertyNames
Object.getOwnpropertyNames
参数就是这个对象
返回值就是获取的所有属性,是一个数组
即使属性设置了特性,也可以获取
不能获取原型上的属性

让原型属性不可枚举,使用方式:
Object.defineProperty(类的原型对象, property, {
enumerable: false //不可枚举
})

查看属性特性

ES5新增一个方法,Object.getOwnPropertyDescriptor()可以查看属性的特性
Object.getOwnPropertyDescriptor(obj, prop)
obj 表示这个对象
prop 表示这个属性
返回值是一个特性对象
特性总结
1 对象原有的属性,特性默认值都是true (writable, enumerable configurable)
2 特性方法为对象新增的属性,特性默认值都是false
3 特性中的set,get与value,writable不兼容
4 属性的特性默认优先设置value和writable

17 原型扩展

判断原型
ES5新增了一个isPrototypeOf方法可以判断对象的原型对象
注意:这个方法查找整个原型链
用法:类的原型.isPrototypeOf(对象)
类的原型是否被对象继承了(对象的原型链上是否可以找到这个类)

18 操作原型

获取原型:Object.getPrototypeOf
以前获取对象的原型用__proto__,但是__proto__属性以__开头,属于私有的属性,是不希望我们使用的
因此ES5新增Object.getPrototypeOf方法,用来获取对象的原型
与__proto__属性是等价的
修改原型:Object.setPrototypeOf
该方法用于设置某个对象的原型(继承原型)
使用方式:Object.setPrototypeOf(obj, prototype)
obj: 要设置新的原型的对象
prototype: 要设置的新的原型(可以是null可以是一个对象)

19 对象禁拓

对象有四个操作:增(扩展,增加)删(删除)改(修改)查(查看)
对象的禁拓(禁止拓展)就是说
该对象不能拓展属性(新增属性)
但是可以删除属性,修改属性和查看属性
Object.preventExtensions方法,用于取消对象的可拓展性
参数就是这个对象
禁拓是不可逆的,一旦禁拓就无法解除
查看是否禁拓:Object.isExtensible
如果返回的是false表示被禁拓了 true表示没有被禁拓,可以新增属性

对象封闭

对象的封闭就是说
不能对对象添加属性,删除属性
但是可以修改属性和查看属性
Object.seal方法,来封闭一个对象
参数就是这个对象
封闭是不可逆的,一旦封闭就无法解封
查看是否封闭:Object.isSealed
如果返回true表示被封闭了,反之则没有

对象冻结

对象的冻结就是说
不能对对象添加属性,删除属性,修改数据
只能查看属性
Object.freeze方法,来冻结一个对象
参数就是这个对象
冻结是不可逆的,一旦冻结就无法解封
查看是否冻结:Object.isFrozen
如果返回true表示被冻结了,反之则没有

        // 对象的操作
        var obj = {
            color: 'red',
            num: 100
        }
        // 禁拓
        // Object.preventExtensions(obj);
        // // 查看禁拓    返回的是false表示被禁拓了	
        // console.log(Object.isExtensible(obj));

        // 对象封闭
        // Object.seal(obj);
        // // 查看是否封闭    如果返回true表示被封闭了,反之则没有
        // console.log(Object.isSealed(obj));

        // 对象冻结
        Object.freeze(obj);
        console.log(Object.isFrozen(obj));

        // 拓展属性
        obj.msg = 'hello';
        // 删除属性
        delete obj.num;
        // 修改属性
        obj.color = 'green';
        // 查看属性
        console.log(obj);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值