精选文章 Vue,手写基础代码

Vue,手写基础代码

作者:lcmanito 时间: 2020-08-04 09:43:32
lcmanito 2020-08-04 09:43:32

 

 手写 call

call 和 apply 的区别:call 方法接收的是一个参数列表,apply 方法接收的是一个包含多个参数的数组。


1.*context* 存在就使用 *context*,否则是 *window*
2.使用 *Object(context)* 将 *context* 转换成对象,并通过 *context.fn* 将 *this* 指向 *context*
3.循环参数,注意从 1 开始,第 0 个是上下文,后面才是我们需要的参数
4.将参数字符串 *push* 进 *args*
5.字符串和数组拼接时,数组会调用 *toString* 方法,这样可以实现将参数一个个传入,并通过 *eval* 执行
6.拿到结果返回前,删除掉 *fn*


Function.prototype.call = function(context) { 
   context = context ? Object(context) : window;
   context.fn = this;    let args = [];    
   for (let i = 1; i < arguments.length; i++) {        
           args.push('arguments['+ i +']');    
           }    
       let res = eval('context.fn('+ args +')');   
    delete context.fn;    return res;
    }

手写 apply


1.apply 无需循环参数列表,传入的 args 就是数组
2.但是 args 是可选参数,如果不传入的话,直接执行


Function.prototype.apply = function(context, args) {
    context = context ? Object(context) : window;    
    context.fn = this;    if (!args) {
            return context.fn();    
        }    
   let res = eval('context.fn('+ args +')');   
    delete context.fn;    return res;
    }
 

手写 bind


1.*bind* 的参数可以在绑定和调用的时候分两次传入
2.*bindArgs* 是绑定时除了第一个参数以外传入的参数,*args* 是调用时候传入的参数,将二者拼接后一起传入
3.如果使用 *new* 运算符构造绑定函数,则会改变 *this* 指向,*this* 指向当前的实例
4.通过 *Fn* 链接原型,这样 *fBound* 就可以通过原型链访问父类 *Fn* 的属性


Function.prototype.bind = function(context) {
    let that = this;    
    let bindArgs = Array.prototype.slice.call(arguments, 1);    
    function Fn () {};    
    function fBound(params) {
            let args = Array.prototype.slice.call(arguments) ;
            return that.apply(this instanceof fBound ? this : context, bindArgs.concat(args));    }    
     Fn.prototype = this.prototype;    
     fBound.prototype = new Fn();    
     return fBound;
  }
 

手写 new

1.*Constructor* 就是 *new* 时传入的第一个参数,剩余的 *arguments* 是其他的参数
2.使用*obj.__proto__ = Constructor.prototype* 继承原型上的方法
3.将剩余的 *arguments* 传给 *Contructor* ,绑定 *this* 指向为 *obj*,并执行
4.如果构造函数返回的是引用类型,直接返回该引用类型,否则返回 *obj*


const myNew = function() {
    let Constructor = Array.prototype.shift.call(arguments);
    let obj = {};    
    obj.__proto__ = Constructor.prototype;    
    let res = Constructor.apply(obj, arguments);    
    return res instanceof Object ? res : obj;
  }
 

手写 instanceOf

1.在 left 的原型链中层层查找,是否有原型等于 prototype
2.确定边界条件,如果 left === null,即找到头没找到返回 false,right === left,即找到返回 true3.left = left.__proto__,不停的向上查找


const myInstanceof = function(left, right) {
    right = right.prototype;    
    left = left.__proto__;    while (true) {
            if (left === null) {
                        return false;        
            }        
            if (right === left) {           
                return true;        
            }        
            left = left.__proto__;    
     }}

 

 手写 Object.create

新建一个空的构造函数 F ,然后让 F.prototype 指向 obj,最后返回 F 的实例


const myCreate = function (obj) {
  function F() {};
  F.prototype = obj;
  return new F();
}

 

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:openstack glance 服务特性

下一篇:吃饭理论,抓沙理论,杯子理论——结构化学习,实现N+1,时间管理

您可能感兴趣

  • grafana使用MYSQL数据源展示

    新增数据源 Grafana支持许多不同的数据源。每个数据源都有一个特定的查询编辑器,该编辑器定制的特性和功能是公开的特定数据来源。 官方支持以下数据源:Graphite,InfluxDB,OpenTSDB,Prometheus,Elasticsearch,CloudWatch和KairosDB。 每个数据源的查询语言和能力都是不同的。 你可以把来自多个数据源的数据组合到一个仪表板dashbo...

  • 我是如何失去团队掌控的?一个技术总监的反思

    我是一个不合格的技术总监,在过去的快三个月里。我带着从40多个人的研发团队(包含需求、开发、测试)里抽调出20多个人去为公司开疆拓土。在这快三个月中,我们一起奋战奋斗拼搏。在过程中,我通宵时间超过半个月,干到凌晨4/5点的日子数不胜数,干到凌晨1/2点日子更是习以为常。整个团队绝大多数人近乎两个月没有周末,辛苦异常,是实实在在的高峰体验。但是三个月后,我带着失败和一身的惨痛教训回到公司。 我...

  • Unity渲染教程(九):复杂材质 https://www.jianshu.com/p/5e3af869870f

    Unity渲染教程(九):复杂材质 https://www.jianshu.com/p/5e3af869870f 同样的着色器,不同的贴图 用户界面 到目前为止,我们一直都为我们的材质使用Unity默认的材质监视器,它很耐用,但是Unity的标准着色器长得非常不一样。仿照着标准着色器,让我们一起来为我们自己的着色器创建一个自定义监视器吧。 我们默认的监视器和标准着色器监视器 着色器GUI 我...

  • Linux系统内存

    Linux 内存是后台开发人员,需要深入了解的计算机资源。合理的使用内存,有助于提升机器的性能和稳定性。本文主要介绍Linux 内存组织结构和页面布局,内存碎片产生原因和优化算法,Linux 内核几种内存管理的方法,内存使用场景以及内存使用的那些坑。 从内存的原理和结构,到内存的算法优化,再到使用场景,去探寻内存管理的机制和奥秘。 一、走进Linux 内存 1、内存是什么? 1)内存又称主存...

  • 美团数据库运维自动化系统构建之路

    本文整理自美团点评技术沙龙第10期:数据库技术架构与实践。 美团点评技术沙龙由美团点评技术团队主办,每月一期。每期沙龙邀请美团点评及其它互联网公司的技术专家分享来自一线的实践经验,覆盖各主要技术领域。 目前沙龙会分别在北京、上海和厦门等地举行,要参加下一次最新沙龙活动?赶快关注微信公众号“美团点评技术团队”。 本次沙龙主要围绕数据库相关的主题,内容包括美团数据库自动化运维系统构建、点评侧My...

  • 美团点评移动网络优化实践

    本文根据第16期美团点评技术沙龙“移动开发实践(上海站)”演讲内容整理而成。 第18期沙龙:高可用系统背后的基础架构(3月25日)火热来袭!快快点击报名吧。 网络优化对于App产品的用户体验至关重要,与公司的运营和营收息息相关。这里列举两个公开的数据: “页面加载超过3秒,57%的用户会离开。” “Amazon页面加载延长1秒,一年就会减少16亿美金营收。” 在做网络优化前,我们首先要为网络...

  • python学习001

    前言: 1、运维/网络为什么要学习编程? (1)运维/网络中所有已学的命令其实都是已经编制好的程序,创造命令就是编写程序; (2)在云计算领域中,繁琐的命令配置已经不能满足日常需求,深入发展是需要贴近业务/研发的,因此就要能够创造命令/编写程序/开发; (3)网络安全领域中,可以深入理解渗透、攻防等细节,Kali-Linux ,SDN(命令对应网络)夯实技术; (4)对于校招而言,大型互联网...

  • vue的使用

    # node, js运行在浏览器中, 不能拥有操作文件, 二进制等这些功能 运行环境,es规范,提供依赖包(http,io,buffer...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。