JavaScript new、apply call 方法

本文详细介绍了JavaScript中new、apply、call和bind方法的原理、实现和应用场景,包括new关键字在创建实例和改变this指向的作用,以及call和bind如何调整函数的上下文。还探讨了如何利用这些方法进行数据类型判断、类数组操作和数组操作优化。
摘要由CSDN通过智能技术生成

new、apply、call、bind

JavaScript 中的 apply、call和 bind 方法是前端代码开发中相当重要的概念,并且与 this 的指向密切相关
在这里插入图片描述

new的实现

1、让实例可以访问到私有属性
2、让实例可以访问构造函数原型(constructor.prototype)所在原型链上的属性
3、构造函数返回的最后结果是引用数据类型

apply call

结合方法“借用”的原理

Function.prototype.call = function (context, ...args) {
    let context = contextwindow;
    context.fn = this;
    var result = eval('context.fn(...args)');
    delete context.fn
    return result;
}
Function.prototype.apply = function (context, args) {
    let context = context||window;
    context.fn = this;
    let result = eval('context.fn(...args)')
    delete context.fn
    return result;
}

这两个方法是直接返回执行结果而 bind 方法是返回一个函数因此这里直接用 eval执行得到结果

bind

bind 的实现思路基本和 apply 一样但是在最后实现返回结果这里bind 不需要直接执行,因此不再需要用 eval而是需要通过返回一个函数的方式将结果返回之后再通过执行这个结果,得到想要的执行效果

Function.prototype.bind = function (context, ...args) {
    if (typeof this !== "function") {
        throw new Error("this must be a function")
        let self = this;
        let fbound = function () {
            self.apply(this instanceof self ? this : context, args.concat(Array.prototype.slice.call(arguments)));
            if (this.prototype) {
                fbound.prototype = object.create(this.prototype)

                return fbound;
            }
        }
    }
}

new

new 关键词的主要作用
就是执行一个构造函数、返回一个实例对象
根据构造函数的情况,来确定是否可以接受参数的传递

  • 1.创建一个新对象
  • 2.将构造函数的作用域赋给新对象(this 指向新对象)
  • 3.执行构造函数中的代码(为这个新对象添加属性)
  • 4.返回新对象
function Person() {
    this.name = 'Jack'
}

var p = new Person();
console.log(p.name)

输出

Jack

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
new 关键词执行之后总是会返回一个对象要么是实例对象,要么是 return 语句指定的对象

apply & call& bind 原理介绍

call、apply和 bind 是挂在 Function 对象上的三个方法,调用这三个方法的必须是一个函数
在这里插入图片描述

三者的作用都是改变func的this指向。

A对象有个 getName 的方法,B 对象也需要临时使用同样的方法那么这时候可以借用 A对象的 getName 方法

let a = {
    name: "jack",
    getName: function (msg) {
        return msg + " --- " + this.name
    }
}

let b = {
    name: "lili"
}

console.log(a.getName("hello"))
console.log(a.getName.call(b,"传奇"))
console.log(a.getName.apply(b,["DNF"]))
let name = a.getName.bind(b,"QQ飞车");
console.log(name())

输出:

hello --- jack
传奇 --- lili  
DNF --- lili   
QQ飞车 --- lili

应用场景

判断数据类型

用 Object.prototype.toString几乎可以判断所有类型的数据

function getType(obj) {
    let type = typeof obj;
    if (type !== "object") {
        return type;
    }
    return Object.prototype.toString.call(obj).replace(/^$/, '$1')
}

console.log(getType(1))

输出:

number

类数组借用方法

let arrayLike = {
    0: 'java',
    1: 'script',
    length: 2
}
Array.prototype.push.call(arrayLike, 'jack', 'lily')
console.log(typeof arrayLike);
console.log(arrayLike)

输出:

object                                                             
{ '0': 'java', '1': 'script', '2': 'jack', '3': 'lily', length: 4 }

获取数组的最大/最小值

用 apply 来实现数组中判断最大/最小值
apply 直接传递数组作为调用方法的参数
也可以减少一步展开数组

let arr = [13, 6, 10, 11, 16]
const max = Math.max.apply(Math, arr);
const min = Math.min.apply(Math, arr);
console.log(max);//16console.log(min);//16
console.log(min);//16console.log(min);//6

输出:

16
6 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学知识拯救世界

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值