靡不有初,鲜克有终
不积跬步无以至千里
1、ajax
- 具体实现
const ajax = {
get (url, callBack) {
const xhr = new XMLHttpRequest()
xhr.open('GET', url, true)
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
callBack(JSON.parse(xhr.response))
}
}
xhr.send()
},
post (url, data, callBack) {
const xhr = new XMLHttpRequest()
xhr.open('POST', url, true)
// 注意:在post请求中,必须在open和send之间添加HTTP请求头
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
callBack(xhr.responeText)
}
}
xhr.send(data)
}
}
const baseUrl = 'https://www.fastmock.site/mock/c65ee7ef23bb5e125732b853ebef16b6/SquirrelSpace'
ajax.get(
baseUrl + '/login',
(res) => {
console.log('最后的结果:', res);
}
)
-
readyState
-
定义
- 指运行
ajax所经历过的几种状态,无论访问是否成功都将响应的步骤,可以理解成为ajax运行步骤。如:正在发送,正在响应等,由ajax对象与服务器交互时所得
- 指运行
-
运行的各个过程的值和含义 0 - (未初始化),还没有调用
send()方法,在定义后自动具有的状态值 1 - (载入),已调用send()方法,正在发送请求 2 - (载入完成),send()方法执行完成 3 - (交互),正在解析响应内容 4 - (完成),响应内容解析完成,可以在客户端调用了
-
Note: 市面上已经有很多的成熟框架,比如axios、fetch、jQuery等,使用方式大同小异,这里只进行了简易的手写。
2、new
- 思路
new关键字会进行如下的操作:- 创建一个空的简单对象,因为
new操作符会返回一个对象 - 将新对象的内部属性
__proto__指向构造函数Func的原型 - 将步骤1新创建的空对象作为
this的上下文 - 如果该函数没有返回对象,则返回
this,也就是newObj
- 创建一个空的简单对象,因为
-
代码
// new: 运算符创建一个 用户定义的对象类型的实例或具有构造函数的内置对象的 实例 function myNew (Func, ...args) { // 创建一个对象,因为new操作符会返回一个对象 let newObj = {} // 将对象与构造函数原型链接起来 // 将新对象的内部属性__proto__指向构造函数的原型,这样新对象就可以访问原型中的属性和方法 newObj.__proto__ = Func.prototype // Object.setPrototypeOf(newObj, Func.prototype) // 将构造函数中的this指向这个newObj对象,并传递参数 let result = Func.apply(newObj, args) // let result = Func.call(newObj, ...args) console.log('result', result); console.log('newObj', newObj); // 如果该函数没有返回对象,则返回newObj return result instanceof Object ? result : newObj // return typeof result === "object" ? result : newObj; }a、未返回对象
function tesFunc (...args) { console.log('打印一下...', ...args); // return { testFeild: 'testFeild' } } // 原生new var resultA = new tesFunc('A', 'A'); // 手写new var resultB = myNew(tesFunc, 'B', 'B'); console.log('resultA', resultA); console.log('resultB', resultB);结果:
b、返回对象
function tesFunc (...args) { console.log('打印一下...', ...args); return { testFeild: 'testFeild' } } // 原生new var resultA = new tesFunc('A', 'A'); // 手写new var resultB = myNew(tesFunc, 'B', 'B'); console.log('resultA', resultA); console.log('resultB', resultB);结果:
-
原型链图解
3、instanceof
-
思路
- 首先获取对象的原型
- 然后获得类型的原型
- 然后一直循环判断对象的原型是否等于类型的原型,直到对象原型为
null,因为原型链最终为null
-
代码
function myInstanceof (left, right) { let proto = left.__proto__; let prototype = right.prototype while (true) { if (proto === null) return false if (proto === prototype) return true proto = proto.__proto__; } } // 原生API用法 console.log({} instanceof Object) // true // 手写instanceof console.log(myInstanceof({}, Object)); // true
-
总结
instanceof的原理其实就是一个查找原型链的过程- 用来检测一个对象在其原型链中是否存在一个构造函数的
prototype属性
4、最后
这篇文章仅仅用于记录手写代码。
优质参考链接👇: