1. 实现一个new操作符
在实现之前,首先分析new操作符做了什么事
复制代码
-
构建了一个全新的对象: var obj = {}
-
new通过构造函数创建出的实例可以访问到构造函数原型链的属性 : obj.propt = fn.Prototype
-
改变this的指向,让fn里的this指向新构建的对象,并执行fn函数体: const ret = fn.apply(obj)
-
判断fn的返回值类型,如果是对象,就返回ret,如果是值类型,就返回obj
function _new (fn , ...args) {
var obj = {}
obj.__proto = fn.prototype
const ret = fn.apply(obj, args)
return typeof ret === 'object' ? ret : obj
}
复制代码
2. 实现深浅copy
在实现之前,我们要先知道什么是深浅拷贝
复制代码
- 浅拷贝: 只复制指向某个对象的指针,而不复制对象本身,新旧对象共享一块内存
- 深拷贝: 复制并创建一个一摸一样的对象,不共享内存,修改新对象,旧对象保持不变
function shallowCopy(obj) {
if (typeof obj !== 'object') return
let newobj = obj instanceof Array ? [] : {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newobj[key] = obj[key]
}
}
return newobj
}
复制代码
function deepCopy(obj) {
if (typeof obj !== 'object') return
var newobj = obj instanceof Array ? [] : {}
for (var key in obj) {
newobj[key] = typeof obj[key] === 'object' ? deepCopy(obj[key]) : obj[key]
}
return newobj
}
复制代码
3. instanceof的实现
在深浅copy里我们使用到了instanceof方法,接下来我们实现一下这个方法,我们已经知道它是用来判断值的类型的了。但是其实上,他的真正作用的用来判断某个对象是不是另一个对象的实例
复制代码
function _instanceof(left, right) {
let L = left.__proto__
let R = right.prototype
while(true) {
if (L === null) return false
if (L === R) return true
L = L.__proto__
}
}
复制代码
4.手写call,apply,bind
三者的不同与用法
复制代码
- call 接收多个参数,第一个为函数上下文也就是this,后边参数为函数本身的参数
- apply 接收两个参数,第一个参数为函数上下文this,第二个参数为函数参数只不过是通过一个数组的形式传入的
- bind 接收多个参数,第一个是bind返回值返回值是一个函数上下文的this,不会立即执行。
Function.prototype.mycall = function (context, ...args) {
context = context || window
const key = Symbol()
context.key = this
return context.key(...args)
delete context.key()
}
复制代码
Function.prototype.myapply = function (context, args) {
context = context || window
const key = Symbol()
context.key = this
return context.key(...args)
delete context.key()
}
复制代码
Function.prototype.mybind = function (context) {
context = (typeof context === 'object' ? context : window)
return (...args) => {
console.log(args)
this.call(context, ...args)
}
}
复制代码
5. 防抖节流
- 防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
- 节流:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
// 防抖
function debounce (func, delay) {
var timeout
return function () {
clearTimeout(timeout)
timeout = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
复制代码
// 节流
function throttle(func, delay) {
var last = 0
return function() {
var now = Date.now()
if (now > last + delay) {
func.apply(this, arguments)
last = now
} else {
console.log('间隔时间不满足要求')
}
}
}
复制代码
6. 柯里化
- 柯里化(Currying),又称部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。核心思想是把多参数传入的函数拆成单参数(或部分)函数,内部再返回调用下一个单参数(或部分)函数,依次处理剩余的参数
var curry = function (fn) {
var args = [].slice.call(arguments, 1)
return function () {
var newArgs = args.concat([].slice.call(arguments))
return fn.apply(this, newArgs)
}
}
复制代码
7. 继承
//原型链+构造函数
function Parent(value) {
this.val = value
}
Parent.prototype.getValue = function () {
console.log(this.val)
}
function Child(value) {
Parent.call(this, value)
}
Child.prototype = new Parent()
复制代码
//寄生组合继承
function Parent(value) {
this.val = value
}
Parent.prototype.getValue = function () {
console.log(this.val)
}
function Child(value) {
Parent.call(this, value)
}
Child.prototype = Object.create(Parent.prototype, {
constructor: {
value: Child,
enumerable: false,
writable: true,
configurable: true
}
})
复制代码
//class继承
class Parent {
constructor(value) {
this.val = value
}
getValue() {
console.log(this.val)
}
}
class Child extends Parent {
constructor(value) {
super(value)
this.val = value
}
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END






















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)