ES5实现原生/ES6方法
实现 bind apply call 方法
实现call
Function.prototype.myCall = function (context, ...args) {
context = context || window;
// 这里使用fn可能存在context已有对应属性,不严谨,可以使用Symbol对象生成唯一属性key
context.fn = this;
const res = context.fn(...args);
delete context.fn;
return res;
}
实现apply
Function.prototype.myApply = function (context, args) {
context = context || global;
// 这里使用fn可能存在context已有对应属性,不严谨,可以使用Symbol对象生成唯一属性key
context.fn = this;
const res = context.fn(...args);
delete context.fn;
return res;
}
实现bind
bind 返回一个原函数的拷贝,并拥有指定的this
值和初始参数。
因此需要存储一下 初始参数,调用的时候,将初始参数和传入的参数合并
Function.prototype.myBind = function (context) {
context = context || window;
const self = this;
let args = [...arguments].slice(1);
console.log('args', args)
return function () {
return self.myApply(context, args.concat([...arguments]))
};
}
测试方法可以参考DEMO/JS
instanceOf 实现
instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
function myInstanceOf(obj, constructor) {
let proto = Object.getPrototypeOf(obj);
// 也可以使用__proto__
// let proto = obj.__proto__;
while (proto) {
if (proto === constructor.prototype) {
return true
}
proto = Object.getPrototypeOf(proto);
// proto = proto.__proto__;
}
return false;
}
Json.stringify Json.parse实现
遍历对象,将对象转换为字符串,需要对 null boolean null undefined 特殊判断
function jsonStringify(obj) {
const type = typeof obj;
if (type !== 'object' || obj === null) {
if (/string|undefined/.test(type)) {
obj = `"${obj}"`
}
return `${obj}`;
} else {
const isArr = Array.isArray(obj);
const res = [];
for (const key in obj) {
let v = obj[key];
const type = typeof v;
if (/string|undefined/.test(type)) {
v = `"${v}"`
} else if (type === 'object') {
v = jsonStringify(v);
}
res.push(`${isArr ? '' : `"${key}":`}${String(v)}`);
}
return `${isArr ? '[' : '{'}${String(res)}${isArr ? ']' : '}'}`
}
}
通过递归的方式,将字符串转换为对象,其中null boolean undefined 需要转化为对应的值
function jsonParse(jsonStr) {
let i = 0;
let curChar = jsonStr[i]
// 步进器
function next() {
i += 1;
curChar = jsonStr[i];
}
function parseValue() {
switch (curChar) {
case '"':
return parseString()
case "{":
return parseObject();
case '[':
return parseArray();
default:
return parseOther();
}
}
function parseString() {
let str = '';
next()
while (jsonStr[i] !== '"') {
str += jsonStr[i];
i++;
}
next();
return str === 'undefined' ? undefined : str;
}
function parseArray() {
let arr = [];
next();
while (curChar !== ']') {
arr.push(parseValue());
if (curChar === ',') {
// 跳过, 下一个
next();
}
}
next();
return arr;
}
function parseObject() {
let obj = {};
next();
while (curChar !== '}') {
let key = parseString();
next();
let value = parseValue();
obj[key] = value;
if (curChar === ',') {
// 跳过
next();
}
}
next();
return obj;
}
function parseOther() {
let str = '';
while (curChar !== ',' && curChar !== ']' && curChar !== '}') {
str += curChar;
next();
}
if (!isNaN(str)) return Number(str);
if (str === 'null') return null;
if (str === 'true') return true;
if (str === 'false') return false;
return str;
}
return parseValue()
}
Last updated