最新这JS十二个进阶知识点,你会写几个?,面试宝典

面试准备+复习分享:

为了应付面试也刷了很多的面试题与资料,现在就分享给有需要的读者朋友,资料我只截取出来一部分哦

秋招|美团java一面二面HR面面经,分享攒攒人品

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

}

let child1 = new Child();

复制代码

优点:可以传参。

缺点:child1拿不到Parent原型上面的方法

组合继承

function Parent () {

this.names = “舔狗的泪”;

}

Parent.prototype.getName=()=>{}

function Child () {

Parent.call(this,‘可以传参’)

}

Child.prototype=new Parent()

let child1 = new Child();

复制代码

优点:可以传参 可以拿到父原型上面的方法。

缺点:new Child()时候 Child里面的Parent方法执行了一次,Child.prototype=new Parent()又执行了Parent方法。

寄生继承

function createP(original) {

//下面一行的代码意思 clone.prototype={ name: ‘舔狗的泪’ }

var clone = Object.create(original);

clone.getName = function () {

// 以某种方式来增强对象

console.log(this.name)

};

return clone;

}

var parent = { name: ‘舔狗的泪’ };

var child = createP(parent);

复制代码

缺点1:不能向Parent里面传参。

缺点2:多个实例对引用类型的操作会被修改

寄生组合继承

function Parent () {

this.names = [“舔狗的泪”];

}

Parent.prototype.getName=()=>{}

function Child () {

Parent.call(this,‘可以传参’)

}

Child.prototype=Object.create(Parent.prototype)

Child.prototype.fn=()=>{}

let child1 = new Child();

复制代码

上面的缺点都优化了

call、apply、bind实现

call 可以支持多个参数

用法:fn1.myCall1(‘指向’,‘参数1’,‘参数2’)

Function.prototype.myCall1 = function (context,…arg) {

// 如果没有传或传的值为空对象 context指向window

context = context || window;

let fn = mySymbol();

context[fn] = this; //给context添加一个方法 指向this

// 处理参数 去除第一个参数this 其它传入fn函数

const result = contextfn; //执行fn

delete context[fn]; //删除方法

//返回函数调用的返回值

return result;

};

复制代码

分析:context[fn] 被指向的对象context下面加一个fn属性,这个fn属性对应就是需要改变this指向的函数,context[fn]()执行。里面的this就指向context,因为是context调用的它。

apply

用法:fn.myApply(‘指向’,[‘参数1’,‘参数2’]),和call基本相同。

Function.prototype.myApply = function (context, args) {

context = context || window;

args = args ? args : [];

const fn = Symbol();

context[fn] = this;

const result = contextfn;

delete context[fn];

return result;

};

复制代码

bind

bind有必要分析一波,大多数人真不一定懂。用法:fn.myBind(‘指向’,‘参数1’)(‘参数2’)。

Function.prototype.myBind = function (context) {

if (typeof this !== ‘function’) {

throw new Error(‘请bind一个函数’);

}

var self = this;

var args = Array.prototype.slice.call(arguments, 1);

var fBound = function () {

var funArgs = Array.prototype.slice.call(arguments);

return self.apply(

this instanceof fNOP ? this : context,

args.concat(funArgs)

);

};

var fNOP = function () {};

fNOP.prototype = this.prototype;

fBound.prototype = new fNOP();

return fBound;

};

复制代码

为什么要做这一行判断this instanceof fNOP ? this : context,当bind后作为一个构造函数的时候,是不用改变this的指向。结合看下图,此时 fBound 中的this是指向a的 。this instanceof fNOP ===true

let A=Animal.bind(Cat,name)

let a=new A()

复制代码

为啥要写下面几行代码?

当Animal的原型上存在其他方法,a是拿不到的。

var fNOP = function () {};

fNOP.prototype = this.prototype;

fBound.prototype = new fNOP();

复制代码

那为啥不直接 fBound.prototype=this.prototype?

因为如果fBound.prototype=this.prototype后,fBound.prototype和this.prototype指针指向同一个内存空间,fBound.prototype改变后会影响this.prototype

new的实现原理

  1. 创建一个空对象

  2. 这个新对象 原型 的连接

  3. 执行构造函数方法,属性和方法指向创建的对象

  4. 如果构造函数中没有返回其它对象,那么返回this,即创建的这个的新对象,否则,返回构造函数中返回的对象。

function _new(){

let targetObj={}

let [constructor,…args]=[…arguments]

targetObj.proto=constructor.prototype

let result =constructor.apply(targetObj,args)

if(result&&(typeof (result)=‘object’||typeof (result)=‘function’)){

return result

}

return targetObj

}

复制代码

compose

redux applyMiddleware 源码的精华也是compose方法,把中间件串起来执行。大家有空可以看看redux源码,写的真的牛逼。我高仿源码compose带传参功能。

function middleware1(x){

return x+1

}

function middleware2(x){

return x+1

}

function middleware3(x){

return x+1

}

function middleware4(x){

return x+1

}

function compose(…funcs) {

return arg => funcs.reduceRight((composed, f) => f(composed), arg);

}

compose(middleware1,middleware2,middleware3,middleware4)(0)

复制代码

深拷贝

没有用WeakMap版本的,循环引用会死循环导致内存泄漏

function deepClone1(obj){

if(typeof obj===‘object’&&obj!==null){

let obj1=Array.isArray(obj) ? [] : {}

for (let key in obj) {

if (obj.hasOwnProperty(key)) {

obj1[key] = deepClone(obj[key]) // 递归拷贝

}

}

return obj1

}

return obj

}

let test={name:‘aa’,age:18}

test.a=test

let test1=deepClone1(test) //会报错 ,内存溢出

复制代码

引用WeakMap,可以处理上面的溢出问题,Map和WeakMap都可以处理

function deepClone2(obj, hash = new WeakMap()){

if(typeof obj===‘object’&&obj!==null){

if (hash.has(obj)) {

return hash.get(obj);

}

言尽于此,完结

无论是一个初级的 coder,高级的程序员,还是顶级的系统架构师,应该都有深刻的领会到设计模式的重要性。

  • 第一,设计模式能让专业人之间交流方便,如下:

程序员A:这里我用了XXX设计模式

程序员B:那我大致了解你程序的设计思路了

  • 第二,易维护

项目经理:今天客户有这样一个需求…

程序员:明白了,这里我使用了XXX设计模式,所以改起来很快

  • 第三,设计模式是编程经验的总结

程序员A:B,你怎么想到要这样去构建你的代码

程序员B:在我学习了XXX设计模式之后,好像自然而然就感觉这样写能避免一些问题

  • 第四,学习设计模式并不是必须的

程序员A:B,你这段代码使用的是XXX设计模式对吗?

程序员B:不好意思,我没有学习过设计模式,但是我的经验告诉我是这样写的

image

从设计思想解读开源框架,一步一步到Spring、Spring5、SpringMVC、MyBatis等源码解读,我都已收集整理全套,篇幅有限,这块只是详细的解说了23种设计模式,整理的文件如下图一览无余!

image

搜集费时费力,能看到此处的都是真爱!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

避免一些问题

  • 第四,学习设计模式并不是必须的

程序员A:B,你这段代码使用的是XXX设计模式对吗?

程序员B:不好意思,我没有学习过设计模式,但是我的经验告诉我是这样写的

[外链图片转存中…(img-cRLKWOv0-1715682727500)]

从设计思想解读开源框架,一步一步到Spring、Spring5、SpringMVC、MyBatis等源码解读,我都已收集整理全套,篇幅有限,这块只是详细的解说了23种设计模式,整理的文件如下图一览无余!

[外链图片转存中…(img-0WjvOkDw-1715682727500)]

搜集费时费力,能看到此处的都是真爱!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 26
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值