實現深度克隆
原理:
- 遍歷對象
- 判斷對象屬性是不是原始值
- 判斷對象屬性是數組還是對象
- 建立響應數組和對象
- 遞歸
function deepClone(origin, target) {
var target = target || {},
toStr = Object.prototype.toString,
arrStr = [object Array];
for(var prop in origin) {
if(origin[prop] != null && typeof origin[prop] == 'obejct') {
target[prop] = toStr.call(origin[prop]) == arrStr ? [] : {};
deepClone(origin[prop], target[prop]);
}else {
target[prop] = origin[prop];
}
}
return target;
}
實現關鍵字new的功能
作用:創建構造函數的對象實例;
原理:
- 創建了空對象,並作爲返回的對象實例
- 將這個對象的原型指向構造函數的prototype屬性
- 將構造函數this指向這個空對象
- 執行構造函數
function _new() {
// 移除args裏的第一個參數並返回,即構造函數
var Func = [].shift.call(arguments);
// 創建一個空對象,並繼承func的prototype
var obj = Object.create(Func.prototype);
// 將func的this指向空對象並執行
var result = Func.apply(obj, arguments);
// 若構造函數返回了對象,則直接返回,否則返回創建的對象obj
return (typeof result == 'object' && result != null) ? result : obj;
}
function Person (name, age) {
this.name = name;
this.age = age;
return this;
}
var person = _new(Person, 'aa', 10);
console.log(person); //{name: 'aa', age: 10}
實現call、apply、bind功能
作用:改變this指向
//實現call
Function.prototype.myCall = function (context, ...args) {
if (context instanceof Object) {
context.fn = this;
var result = context.fn(...args);
delete context.fn;
} else {
var temp = new Object(_this);
temp.fn = this;
var result = temp.fn(...args);
delete temp.fn;
}
return result;
}
//實現apply
Function.prototype.myApply = function (context, args) {
if (context instanceof Object) {
context.fn = this;
var result = context.fn(...args);
delete context.fn;
} else {
var temp = new Object(context);
temp.fn = this;
var result = temp.fn(...args);
delete temp.fn;
}
return result;
}
//實現bind
Function.prototype.myBind = function (context, ...args) {
if (context instanceof Object) {
context.fn = this;
var result = function () {
context.fn(...args);
delete context.fn;
};
} else {
var temp = new Object(context);
temp.fn = this;
var result = function () {
temp.fn(...args);
delete temp.fn;
};
}
return result;
}
常用數組方法的封裝
forEach
作用:遍歷數組
第一個參數(必填):函數,有三個參數分別爲數組元素,數組索引,數組本身
第二個參數(選填):對象,函數的this指向,若沒有填,this指向window
Array.prototype.myForEach = function(func) {
var _arr = this, //數組本身
len = _arr.length, //數組的長度
param2 = arguments[1] || window; //forEach第二個參數
for(var i = 0; i < len; i++) {
func.apply(param2, [_arr[i], i, _arr]);
}
}
filter
作用:過濾數組
第一個參數(必填):函數,有三個參數分別爲數組元素,數組索引,數組本身
第二個參數(選填):對象,函數的this指向,若沒有填,this指向window
在原有的數組上改變,建議克隆原數組再操作
Array.prototype.myFilter = function(func) {
var _arr = this,
len = _arr.length,
param2 = arguments[1] || window,
newArr = [];
for(var i = 0; i < len; i++) {
//返回false,將元素過濾
//返回true,將元素加入新數組
func.apply(param2, [_arr[i], i, _arr]) ? newArr.push(deepClone([], _arr[i])) : '';
}
return newArr;
}
map
作用:映射
第一個參數(必填):函數,有三個參數分別爲數組元素,數組索引,數組本身
第二個參數(選填):對象,函數的this指向,若沒有填,this指向window
在原有的數組上改變,建議克隆原數組再操作
Array.prototype.myMap = function(func) {
var _arr = this,
len = _arr.length,
param2 = arguments[1] || window,
newArr = [];
for(var i = 0; i < len; i++) {
newArr.push( deepClone( func.apply(param2, [_arr[i], i, _arr]) ) );
}
return newArr;
}
every
作用:只要有一個元素不符合條件就停止遍歷,返回false,若全部符合就返回true
第一個參數(必填):函數,有三個參數分別爲數組元素,數組索引,數組本身
第二個參數(選填):對象,函數的this指向,若沒有填,this指向window
在原有的數組上改變,建議克隆原數組再操作
Array.prototype.myEvery = function(func) {
var _arr = this,
len = _arr.length,
param2 = arguments[1] || window;
for(var i = 0; i < len; i++) {
if(!func.apply(param2, [_arr[i], i, _arr])) {
return false;
}
}
return true;
}
some
作用:只要有一個元素符合條件就停止遍歷,返回true,若全部都不符合就返回false
第一個參數(必填):函數,有三個參數分別爲數組元素,數組索引,數組本身
第二個參數(選填):對象,函數的this指向,若沒有填,this指向window
在原有的數組上改變,建議克隆原數組再操作
Array.prototype.mySome = function(func) {
var _arr = this,
len = _arr.length,
param2 = arguments[1] || window;
for(var i = 0; i < len; i++) {
if(func.apply(param2, [_arr[i], i, _arr])) {
return true;
}
}
return false;
}