zoukankan      html  css  js  c++  java
  • 9.10,,,实现new instanceof apply call 高阶函数,偏函数,柯里化

    链式调用
    
    let obj = {
      a: 0,
      f1() {
        this.a += 1
        console.log(this.a)
        return this
      },
      f2() {
        this.a += 2
        console.log(this.a)
        return this
      },
      f3() {
        this.a += 3
        console.log(this.a)
        return this
      }
    }
    // obj.f1().f1().f1()//1 2 3
    // obj.f2().f2().f2()//5 7 9
    // obj.f3().f3().f3()//12 15 18
    obj.f1().f2().f3()//1 3 6
    

      

    new
    
    function Person(name) {
      this.name = name
    }
    let p  = new Person('name')
    function New() {
      let obj = {  }
      obj.__proto__ = Person.prototype
      Person.apply(obj,Array.prototype.slice.call(arguments, 1))
      return typeof obj === 'object' ? obj : {}
    }
    let p1 = New(Person,'name')
    console.log(p1)
    //Person {name: "name"}
    //name: "name"
    //__proto__:
    //constructor: ƒ Person(name)
    //__proto__: Object
    function New1(f) {
      //返回一个func
      return function () {
          var o = {"__proto__": f.prototype};
          f.apply(o, arguments);//继承父类的属性
          return o; //返回一个Object
      }
    }
    var p2 = New1(Person)("Jack",25);
    console.log(p2)
    
    // 判断Test 是否是被new执行的
    function Test() {
      console.log(new.target)
    }
    Test() // undefined
    new Test() // [Function: Test] 也就是 new.target === Test
    intanceof
    
    
    function Instanceof(obj,fn) {
      if(typeof fn !== 'function'){
        throw new Error('instance error')
      }
      if (!obj || (typeof obj !== 'object' && typeof obj !== 'function')) {
        return false
      }
      let type = fn.prototype  //原型对象
      while (obj.__proto__) { //对象原型
        if (obj.__proto__ === type) {
          return true
        }
        obj = obj.__proto__
      }
      return false
    }
    console.log(Instanceof([],Array))//true
    console.log(Instanceof([],Function))//false
    console.log([] instanceof Function)//false
    //call apply
    
    Function.prototype.Call(context) {
      if (typeof context === 'undefined' || context === null) {
        context = window
      }
      context.fn = this //调用Call的那个函数
      let args = [...argments].slice(1)
      context.fn(...agrs) //apply就直接参数数组参数
      delete context.fn
    }
    //例子
    Function.prototype.Call = function (context) {
      console.log(context) //{ name: 'Tom1' }
      if (typeof context === 'undefined' || context === null) {
        context = window
      }
      console.log(context) //{ name: 'Tom1' }
      context.fn = this
      console.log(this,context.fn) //[Function: say] [Function: say]
      let args = [...arguments].splice(1)
      context.fn(...args)
      console.log(args) //[ 1 ]
      delete context.fn
    }
    let Person1 = {
      name: 'Tom',
      say(age) {
          //console.log(this)
          console.log(`我叫${this.name}+${age}`)
      }
    }
    // 先看代码执行效果
    Person1.say() //我叫Tom 
    Person2 = {
      name: 'Tom1'
    }
    Person1.say.call(Person2) //我叫Tom1
    Person1.say.Call(Person2,1)
    
    //例2扩展用法
    function Doctor(name){
      this.name = name;
      this.say = function(){
          console.log(this.name)
      }
    }
    function Stephen(name){
      //当前函数内的this指向函数Son的实例化对象
      //在执行Stephen时执行Doctor,同时将Doctor内的this改变成Stephen的this
      Doctor.Call(this,name)
    }
     var doctor = new Doctor("Doctor")
     doctor.say();       //Doctor
     var stephen = new Stephen("Stephen Strange")
    // // 在Stephen中并没有say方法,但是因为在new Stephen时,执行了Doctor,
    // // 并将Doctor中的this指向Stephen的this,
    // // 那么在new Stephen后,得到的实例,也具有了Doctor内的属性和方法
     stephen.say();      //Stephen Strange
    
    
    
    //bind
    //高阶函数
    //JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
    function add(x, y, f) {
        return f(x) + f(y);
    }
    console.log(add(-5, 6, Math.abs)) //11
    //偏函数
    //固定一个或者几个参数,返回一个新的函数,接收剩下的参数
    function add(a,b){ //固定参数
      return a + b;
    }
    //生产偏函数的工厂
    function partial(fn,a){
      return function(b){
          return fn(a,b);
      }
    }
    var parAdd = partial(add,1);//变量parAdd接受返回的新函数
    console.log(parAdd(2));//在调用的时候传入剩余的参数
    console.log(parAdd(3));//在调用的时候传入剩余的参数
    console.log(parAdd(4));//在调用的时候传入剩余的参数
    //柯里化sum(1)(2)(3)...
    //把接收多个参数的函数转换成多个接收一个参数的函数----可以延迟执行 ,bind也是
    //因为没满足原参数个数就不会返回结果
    //辅助函数
    function sub_curry(fn) {
      let args = [...arguments].slice(1)
      return function () {
        return fn.apply(this.args.concat([...arguments]))
      }
    }
    function curry(fn,length){
       length = length || fn.length//Function.prototype.length 属性,就是为了告诉你这个函数定义了几个参数。
      return function() {
        if(arguments.length < length) {
          let next = [fn].concat(...arguments) //包含fn,因为重复调辅助函数
        return length - arguments.length > 0 
          ? curry(sub_curry.apply(this, combined), length - arguments.length)
          : sub_curry.call(this, combined );
          
        }else {
           return fn.apply(this,arguments) //拿到了原函数的所有参数
        }
      }
    }
    var fn = function(a, b, c) { return [a, b, c]; };
     curry(fn)('a')('a','a')
    console.log( curry(fn)('a','a')('a'))
  • 相关阅读:
    1. Window环境下
    A-Frame 简介03
    A-frame_02
    A-Frame_简单介绍
    iOS_UIWebView加载本地html文件路径问题
    AVAudioRecorder 录制音频
    内存管理, 对象的生命周期
    02-socket编程
    01-socket第三方库 AsyncSocket(GCDAsyncSocket)
    01-MKNetworkKit介绍及使用
  • 原文地址:https://www.cnblogs.com/zjj-study/p/13645779.html
Copyright © 2011-2022 走看看