ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

劫持

2022-06-10 22:36:34  阅读:141  来源: 互联网

标签:劫持 name arr call log fn fn2


劫持

一般来说劫持分为三类:

  • 黑客暴力解码(逆向工程),取用户的私密信息

  • js内置功能的重写

    一般来说,内置功能都是写在原型链中不可更改的,若是取一个名字和内置功能相同,则相当于给对象添加一个对象或是方法

    可以达到保留原来功能的基础上添加或修改,以更符合本身的需求

    // 内置功能的劫持
            var _log = console.log;
            _log('_log功能与原本的console.log相同')
    		// console.log给引用重写添加引用
            console.log = function() {
                // 自己修改的代码
            }
    

    代表:vue框架的点语法

  • this关键字的劫持(重点)

    1. call(调用者,参数...)方法 ,指定this的调用者,可以劫持其他对象里面的方法

      var obj = {name: 'kaller',say = function(str) {
                 console.log(this.name,str)
                }}
      var obj1 = {name: 'lifa'}
      // call()方法改变this的调用者,使用obj1调用obj对象里的say方法
      obj.say.call(obj1,'hello call()')
      // 输出结果: lifa  hello call()
      
    2. apply(调用者,[参数])方法和call()相同,不同的是传入的参数是以数组的方式进行的,空则表示没有参数

      // Math.max() call() 给一个数组,求取最大的值
      var arr = [10,52,155,12]
      // Math.max.apply(0,arr) arr.apply()相当于arr也有Math.max()方法相当于 
      // Math.max(10,52,155,12)
      Math.max.apply(arr,arr) // 第一个arr代表调用者,第二个arr代表arr数组里的值作为参数
      

      注意:apply为空时要写[],不能不写

    3. bind()函数定义的时候就指定this

      bind的优先级高于call和apply

      var obj2 = {name: 'lili'}
      var obj = {name: 'kela',say = function() {
          console.log(this.name)
      }.bind(obj2)}	// 在定义的时候就指定this
      // 如果后面再用call和apply来修改 不起作用
      var obj3 = {name: 'nale'}
      obj.say.call(obj3) 
      // 结果为lili
      

    拓展

    根据官方源代码推出一些规律

    • 所有函数对象都有call方法----------Function.prototype有call方法(原型链思想)
    • 哪个函数调用call方法,就是那个函数运行
    function fn() {
        console.log(1)
    }
    function fn2() {
        console.log(2)
    }
    fn2.call() // 调用者为空,运行fn2函数,结果为2
    fn.call.call(fn2)
    fn.call.call.call(fn2)
    // 结果都为2
    

    分析fn.call.call(fn2)

    1. fn.call是一个函数,每一个函数对象都有call方法

    2. fn2是调用者,运行fn.call()相当于运行fn2.call()

      在js中,fn.call和fn2.call指向的是同一个引用对象

    3. fn2.call()就是运行fn2

    同理分析fn.call.call.call(fn2)

    1. 不管call了多少,最后指向都是Function.prototype里的call方法,相当于一个闭环
    2. 最终的结果都是fn2.call()

    源代码分析

    Function.prototype.mycall = function(That,arr) {
        // this指定是fn函数 That指的是引用的对象obj2
        let name1 = 'lf'+new Date()
        That[name1] = this
        // fn()里的this指的是That
        let re = That.fn()
        // 添加之后要删除对象
        delete That[name1]
        // 函数运行后如果有返回值,则返回
        return re
        
    }
    // obj.fn.call(应用对象名,参数)
    var obj = {name: 'kela',fn:function() {
        console.log(this.name) 
    }}
    var obj2 = {name: 'lili'}
    
    obj.fn.call(obj2)
    /* 自己写源代码mycall实现call方法
    实现功能大概为更改this的指定对象,运行obj.say函数*/ 
    obj.fn.mycall(obj2)
    

标签:劫持,name,arr,call,log,fn,fn2
来源: https://www.cnblogs.com/shuilifang/p/16364830.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有