字数
1241 字
阅读时间
7 分钟
手写 forEach
javascript
// 注意forEach存在一种,forEach(callbackFn, thisArg) 的方式为callbackFn绑定this
Array.prototype.forEach(callback, context) {
if (this === null) {
throw new TypeError('this is null or not undefined')
}
if (typeof callback !== 'function') {
throw new TypeError(callback + " is not a function"); }
const length = this.length;
const that = this;
let i = 0;
while (i < length) {
callback.call(context, that[i], i, that);
i++;
}
}手写 new
es6 中的 class 含义:
js
class Point {
// ...
}
typeof Point // "function"
Point === Point.prototype.constructor // truejavascript
objectFactory(构造函数, 初始化参数);
/**
* 1. 创建一个新对象
* 2. 将构造函数的prototype指向constructor
* 3. 将实例的this指向构造函数
* 4. 判断返回结果
**/js
function objectFactory() {
let newObject = null;
let constructor = Array.prototype.shift.call(arguments);
let result = null;
// 判断参数是否是一个函数
if (typeof constructor !== "function") {
console.error("type error");
return;
}
// 新建一个空对象,对象的原型为构造函数的 prototype 对象
newObject = Object.create(constructor.prototype);
console.log(newObject) // object, 是hlper {} 空对象
// 将 this 指向新建对象,并执行函数
result = constructor.apply(newObject, arguments);
console.log(result) // undefined
// 判断返回对象,如果constructor的返回值是函数或者object,则返回返回值
let flag = result && (typeof result === "object" || typeof result === "function");
// 判断返回结果
return flag ? result : newObject;
}
// 使用方法
function helper(name) {
this.name = name
// return function () {
// console.log('jjj')
// }
return {
name: 'jie'
}
}
let a = objectFactory(helper, 'jiechen');
console.log(a)手写 call 和 apply
使用调用者提供的 this 值和参数调用该函数。若该方法没有返回值,则返回 undefined
javascript
Function.prototype.myCall = function (thisArg) {
if (typeof this !== 'function') {
throw new TypeError("type error");
}
let args = [...arguments].slice(1);
thisArg = thisArg || window;
let result = null;
// 将调用的函数绑定到对象的属性上
thisArg.fn = this;
result = thisArg.fn(...args);
if (arguments[1]) {
result = thisArg.fn(arguments[1]);
} else {
result = thisArg.fn();
}
delete thisArg.fn;
return result;
}
let args = [...arguments].slice(1),fn = this
return function Fn() {
return fn.apply(
this instanceof Fn ? this : thisArg,
// 实现函数柯里化,将使用多个参数的一个函数转为使用一个参数的函数
args.concat(...arguments)
)
}promise
Promise 对象 -- JavaScript 标准参考教程(alpha)
简单介绍
所谓 Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。
例如以下一个 promise 的例子:
javascript
new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('Hello,我是Hy')
},1000)
}).then((res)=>{
console.log(res);//res这个参数就是resolve 调用后传的data,既Hello,我是Hy
},(req)=>{
console.log(req);
})
// 一秒钟后打印 Hello,我是Hy可以看出一个 promise 的构造函数包含两个方法 resolve、reject,同时根据 promise+ 规范可知 promise 包含三个状态:
pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败。
那么我们可以可以根据这三种不同状态去实现 resolve、reject,以及实现 then 方法,那么一个简单的 promise 雏形就出来了。下面来实现它:
javascript
// 手写promise
const PENDING = "pending"
const RESOLVED = "resolved"
const REJECTED = "rejected"
function MyPromise (fn) {
let self = this
this.state = PENDING
this.value = null
this.resolveCallbacks = []
this.rejecteCallbacks = []
function resolve (value) {
if (value instanceof MyPromise) {
return value.then(resolve, reject);
}
if (self.state === PENDING) {
self.state = RESOLVED
self.value = value;
while (self.resolveCallbacks.length) {
self.resolveCallbacks.shift()(self.value)
}
}
}
function reject (value) {
if (self.state === PENDING) {
self.state = REJECTED
self.value = value
while (self.rejecteCallbacks.length) {
self.rejecteCallbacks.shift()(self.value)
}
}
}
try {
fn(resolve, reject)
} catch (e) {
reject(e)
}
}
MyPromise.prototype.then = function (onResolved = data => data, onRejcted) {
// 保存前一个promise的this
let self = this
let promise = new Promise((resolve, reject) => {
// 转换为 异步执行,用来获取 新的 promise
let resolvedHandler = setTimeout(() => {
try {
let res = onResolved(self.value)
// 判断返回值是 promise 还是 普通返回值
resolvePromise(promise, res, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
let rejectedHandler = setTimeout(() => {
try {
let res = onRejected(self.value)
resolvePromise(promise, res, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
let peddingHandler = () => {
// 将回调函数存入数组中等待被执行
self.resolveCallbacks.push(() => {
setTimeout(() => {
try {
let res = onResolved(self.value)
resolvePromise(promise, res, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
}),
self.rejecteCallbacks.push(() => {
setTimeout(() => {
try {
let res = onRejected(self.value)
resolvePromise(promise, res, resolve, reject)
} catch (e) {
reject(e)
}
}, 0)
})
}
// 判断返回值是 promise 还是 普通返回值
function resolvePromise(promise, res, resolve, reject) {
// 循环调用报错
if (promise === res) {
return reject(
throw new TypeError('Chaining cycle detected for promise #<Promise>')
)
}
if (res instanceof MyPromise) {
res.then(resolve, reject)
} else {
resolve(res)
}
}
switch (self.state) {
case PEDING:
peddingHandler();
break;
case RESOLVED:
resolvedHandler()
break;
case REJECTED:
rejectedHandler()
break
}
})
return promise
}
function promiseAll(iterable) {
let counter = 0;
let result = [];
return new MyPromise((resolve, reject) => {
function addData(key, value) {
counter++;
result[key] = value;
counter === iterable.length && resolve(result)
}
iterable.forEach((item, index) => {
item instanceof MyPromise
? item.then(data => addData(index, data),
err => reject(err)
)
: addData(index, item)
})
})
}sleep 函数
异步像同步一样执行,需要异步返回结果之后,再往下依据结果继续执行
javascript
// sleep函数
function sleepFun(time) {
return new Promise(resolve => setTimeout(resolve, time))
}
async function wait(time) {
console.time('time');
await sleepFun(time);
fun();
}
wait(3000); // time: 3001.204833984375msinstanceof
javascript
function myInstanceOf (left, right) {
if (typeof left !== 'object' || left === null || typeof right !== 'function') {
return false;
};
let proto = Obejct.getPrototypeof(left),
prototype = right.prototype;
while (true) {
if (!proto) return false;
if (prototype === proto) return true;
proto = Obejct.getPrototypeof(proto);
}
}