JS面试题之创建对象7种方式,原型链,call/apply/bind(一)

本文介绍了JavaScript中创建对象的多种方式,包括Object构造函数、Object.create、Object.assign、对象字面量、构造函数、构造函数配合prototype以及ES6的class语法。接着,解释了原型链的概念,每个对象如何通过prototype属性形成继承链。最后,详细对比了call、apply和bind的区别,它们都是用于改变函数内部this指向的方法,但调用时机和参数传递方式有所不同。这些知识点是JS面试的常见题目,对于开发者来说非常重要。

我是傲夫靠斯,欢迎关注我的公众号【前端工程师的自我修养】,每天更新。

今天开始,我将不定期的分享一些面试题,答题不是目的,目的帮助我们一起巩固JS的基础知识,让我们平时写代码的时候多一些选择。今天主要是3道题,是JS中比较基础的,也是面试常问的。

今日题目:

  • 在JS里有几种创建对象的方式,分别是什么?
  • 什么是原型链?
  • call、apply和bind有什么区别?

1. 在JS里有几种创建对象的方式,分别是什么?

  1. Object构造函数

    通过这种方式可以创建一个空对象,但现实中不推荐用。

    const object = new Object();
    
  2. Object的create方法

    create方法通过传入一个prototype对象,返回一个新对象。

    const object = Object.create(null);
    
  3. Object的assign方法

    assign方法用来将传入的所有对象的可枚举的属性值复制到一个对象,并返回这个对象

    const object = Object.assign({});
    
  4. 对象字面量

    创建一个空对象和以上的两种方式相同

    const object = {};
    
  5. 构造函数

    创建一个构造函数,使用new操作符来创建对象

    function Person(name){
       this.name = name;
       this.age = 21;
    }
    const object = new Person("傲夫靠斯");   
    
  6. 构造函数配合prototype

    和构造函数相似,但把属性和方法放在prototype上

    function Person(){}
    Person.prototype.name = "傲夫靠斯";
    const object = new Person();
    
  7. ES6的class语法

    ES6引入的新的特性创建对象,和构造函数类似

    class Person {
       constructor(name) {
          this.name = name;
       }
    }
    
    const object = new Person("傲夫靠斯");
    

    如果能答出3种,已经及格了,3种以上就很优秀了。

2. 什么是原型链?

prototype是JS中实现对象继承的方式,在JS中,每个对象都有一个prototype原型对象,原型对象也可能有prototype原型对象,所以这会像一个长长的链条一样,通常称为原型链。

对象的prototype原型可以通过Object.getPrototypeOf(object) 获取,构造函数的原型可通过Object.prototype获取。

function Person(){}
Person.prototype.name = "傲夫靠斯";
const object = new Person();

console.log(Object.getPrototypeOf(object)  === Person.prototype)
//输出: true

3. call、apply和bind有什么区别?

这三个方法的功能是一样的,都是用来改变函数的this指向,只是传参方式和调用时机有所区别,具体看下面的例子。

  • call: 通过call方法调用函数,第一个参数为this指向的对象,第二个参数开始为函数真正的需要传入的参数
const user1 = {name: '傲夫靠斯', age: 21};
const user2 = {name: '晒了太阳', age: 25};

function intro(contury, hobby) {
    console.log(`你好,我叫${this.name},我今年${this.age}岁,我来自${contury},我平时喜欢${hobby}`);
}

intro.call(user1, '中国', '打游戏'); // 你好,我叫傲夫靠斯,我今年21岁,我来自中国,我平时喜欢打游戏
intro.call(user2, '中国', '听音乐'); // 你好,我叫晒了太阳,我今年25岁,我来自中国,我平时喜欢听音乐
  • apply: 通过apply方法调用和call类似,第一个参数也是this指向的对象,区别在于第二个参数是数组,数据的值为函数所需要传入的参数
const user1 = {name: '傲夫靠斯', age: 21};
const user2 = {name: '晒了太阳', age: 25};

function intro(contury, hobby) {
    console.log(`你好,我叫${this.name},我今年${this.age}岁,我来自${contury},我平时喜欢${hobby}`);
}

intro.apply(user1, ['中国', '打游戏']); // 你好,我叫傲夫靠斯,我今年21岁,我来自中国,我平时喜欢打游戏
intro.apply(user2, ['中国', '听音乐']); // 你好,我叫晒了太阳,我今年25岁,我来自中国,我平时喜欢听音乐
  • bind: 与apply和bind不同的是,bind方法传入this所指向的对象,返回一个新的函数。新的函数调用方式和原函数一致。
const user1 = {name: '傲夫靠斯', age: 21};
const user2 = {name: '晒了太阳', age: 25};

function intro(contury, hobby) {
    console.log(`你好,我叫${this.name},我今年${this.age}岁,我来自${contury},我平时喜欢${hobby}`);
}
const introFunc1 = intro.bind(user1)
const introFunc2 = intro.bind(user2)

introFunc1('中国', '打游戏'); // 你好,我叫傲夫靠斯,我今年21岁,我来自中国,我平时喜欢打游戏
introFunc2('中国', '听音乐'); // 你好,我叫晒了太阳,我今年25岁,我来自中国,我平时喜欢听音乐

这道题很常见,几乎是面试必考,只要记住它们都是用来改变函数内this指向的,call和apply都是立即调用,call传参为依次传入,apply传入数组。而bind绑定this指向后返回一个新的函数,可以后调用,传参和原函数一样。

唠叨

今天题目很基础,但很重要

感谢大家的阅读,您的点赞、评论、关注是对我最大的鼓励 O(∩_∩)O👍👍👍

我是傲夫靠斯,微信搜【前端工程师的自我修养】,让我们每天进步一点点,期待更好的自己。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值