JS面试题汇总(一)

如果你对 ===== 的概念不是特别了解,建议大多数情况下使用 ===

6. 怎样添加、移除、移动、复制、创建和查找节点?

参考答案:

1)创建新节点

  • createDocumentFragment() //创建一个 DOM 片段

  • createElement() //创建一个具体的元素

  • createTextNode() //创建一个文本节点

2)添加、移除、替换、插入

  • appendChild() //添加

  • removeChild() //移除

  • replaceChild() //替换

  • insertBefore() //插入

3)查找

  • getElementsByTagName() //通过标签名称

  • getElementsByName() //通过元素的 Name 属性的值

  • getElementById() //通过元素 Id,唯一性

7. 事件委托是什么

参考答案:

利用事件冒泡的原理,让自己的所触发的事件,让他的父元素代替执行!

解析:

1、那什么样的事件可以用事件委托,什么样的事件不可以用呢?

  • 适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。

  • 值得注意的是,mouseover 和 mouseout 虽然也有事件冒泡,但是处理它们的时候需要特别的注意,因为需要经常计算它们的位置,处理起来不太容易。

  • 不适合的就有很多了,举个例子,mousemove,每次都要计算它的位置,非常不好把控,在不如说 focus,blur 之类的,本身就没用冒泡的特性,自然就不用事件委托了。

2、为什么要用事件委托

    1. 提高性能
    • 苹果
    • 香蕉
    • 凤梨
    • // good

      document.querySelector(‘ul’).onclick = (event) => {

      let target = event.target

      if (target.nodeName === ‘LI’) {

      console.log(target.innerHTML)

      }

      }

      // bad

      document.querySelectorAll(‘li’).forEach((e) => {

      e.onclick = function() {

      console.log(this.innerHTML)

      }

      })

        1. 新添加的元素还会有之前的事件。

      3、事件冒泡与事件委托的对比

      • 事件冒泡:box 内部无论是什么元素,点击后都会触发 box 的点击事件

      • 事件委托:可以对 box 内部的元素进行筛选

      4、事件委托怎么取索引?

      • aaaaaaaa
      • 事件委托了 点击当前, 如何获取 这个点击的下标
      • cccccccc
      • window.onload = function() {

        var oUl = document.getElementById(“ul”);

        var aLi = oUl.getElementsByTagName(“li”);

        oUl.onclick = function(ev) {

        var ev = ev || window.event;

        var target = ev.target || ev.srcElement;

        if (target.nodeName.toLowerCase() == “li”) {

        var that = target;

        var index;

        for (var i = 0; i < aLi.length; i++)

        if (aLi[i] === target) index = i;

        if (index >= 0) alert(‘我的下标是第’ + index + ‘个’);

        target.style.background = “red”;

        }

        }

        }

        拓展:

        • 键盘事件:keydown keypress keyup

        • 鼠标事件:mousedown mouseup mousemove mouseout mouseover

        参考

        8. require 与 import 的区别

        参考答案:

        两者的加载方式不同、规范不同

        第一、两者的加载方式不同,require 是在运行时加载,而 import 是在编译时加载

        require(’./a’)(); // a 模块是一个函数,立即执行 a 模块函数

        var data = require(’./a’). data; // a 模块导出的是一个对象

        var a = require(’./a’)[0]; // a 模块导出的是一个数组 ======> 哪都行

        import $ from ‘jquery’;

        import * as _ from ‘_’;

        import {a, b, c} from ‘./a’;

        import {default as alias, a as a_a, b, c} from ‘./a’; ======>用在开头

        第二、规范不同,require 是 CommonJS/AMD 规范,import 是 ESMAScript6+规范

        第三、require 特点:社区方案,提供了服务器/浏览器的模块加载方案。非语言层面的标准。只能在运行时确定模块的依赖关系及输入/输出的变量,无法进行静态优化。

        import 特点:语言规格层面支持模块功能。支持编译时静态分析,便于 JS 引入宏和类型检验。动态绑定。

        9. javascript 对象的几种创建方式

        参考答案:

        第一种:Object 构造函数创建

        var Person = new Object();

        Person.name = “Nike”;

        Person.age = 29;

        这行代码创建了 Object 引用类型的一个新实例,然后把实例保存在变量 Person 中。

        第二种:使用对象字面量表示法

        var Person = {}; //相当于 var Person = new Object();

        var Person = {

        name: ‘Nike’;

        age: 29;

        }

        对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。也就是说,第一种和第二种方式创建对象的方法其实都是一样的,只是写法上的区别不同

        在介绍第三种的创建方法之前,我们应该要明白为什么还要用别的方法来创建对象,也就是第一种,第二种方法的缺点所在:它们都是用了同一个接口创建很多对象,会产生大量的重复代码,就是如果你有 100 个对象,那你要输入 100 次很多相同的代码。那我们有什么方法来避免过多的重复代码呢,就是把创建对象的过程封装在函数体内,通过函数的调用直接生成对象。

        第三种:使用工厂模式创建对象

        function createPerson(name, age, job) {

        var o = new Object();

        o.name = name;

        o.age = age;

        o.job = job;

        o.sayName = function() {

        alert(this.name);

        };

        return o;

        }

        var person1 = createPerson(“Nike”, 29, “teacher”);

        var person2 = createPerson(“Arvin”, 20, “student”);

        在使用工厂模式创建对象的时候,我们都可以注意到,在 createPerson 函数中,返回的是一个对象。那么我们就无法判断返回的对象究竟是一个什么样的类型。于是就出现了第四种创建对象的模式。

        第四种: 使用构造函数创建对象

        function Person(name, age, job) {

        this.name = name;

        this.age = age;

        this.job = job;

        this.sayName = function() {

        alert(this.name);

        };

        }

        var person1 = new Person(“Nike”, 29, “teacher”);

        var person2 = new Person(“Arvin”, 20, “student”);

        对比工厂模式,我们可以发现以下区别:

        1. 没有显示地创建对象

        2. 直接将属性和方法赋给了 this 对象

        3. 没有 return 语句

        4. 终于可以识别的对象的类型。对于检测对象类型,我们应该使用 instanceof 操作符,我们来进行自主检测:

        alert(person1 instanceof Object); //ture

        alert(person1 instanceof Person); //ture

        alert(person2 instanceof Object); //ture

        alert(person2 instanceof Object); //ture

        同时我们也应该明白,按照惯例,构造函数始终要应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。

        那么构造函数确实挺好用的,但是它也有它的缺点:

        就是每个方法都要在每个实例上重新创建一遍,方法指的就是我们在对象里面定义的函数。如果方法的数量很多,就会占用很多不必要的内存。于是出现了第五种创建对象的方法

        第五种:原型创建对象模式

        function Person() {}

        Person.prototype.name = “Nike”;

        Person.prototype.age = 20;

        Person.prototype.jbo = “teacher”;

        Person.prototype.sayName = function() {

        alert(this.name);

        };

        var person1 = new Person();

        person1.sayName();

        使用原型创建对象的方式,可以让所有对象实例共享它所包含的属性和方法。

        如果是使用原型创建对象模式,请看下面代码:

        function Person() {}

        Person.prototype.name = “Nike”;

        Person.prototype.age = 20;

        Person.prototype.jbo = “teacher”;

        Person.prototype.sayName = function() {

        alert(this.name);

        };

        var person1 = new Person();

        var person2 = new Person();

        person1.name = “Greg”;

        alert(person1.name); //‘Greg’ --来自实例

        alert(person2.name); //‘Nike’ --来自原型

        当为对象实例添加一个属性时,这个属性就会屏蔽原型对象中保存的同名属性。

        这时候我们就可以使用构造函数模式与原型模式结合的方式,构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性

        第六种:组合使用构造函数模式和原型模式

        function Person(name, age, job) {

        this.name = name;

        this.age = age;

        this.job = job;

        }

        Person.prototype = {

        constructor: Person,

        sayName: function() {

        alert(this.name);

        };

        }

        var person1 = new Person(‘Nike’, 20, ‘teacher’);

        解析:

        参考

        10. JavaScript 继承的方式和优缺点

        参考答案:六种方式

        • 一、原型链继承

        • 缺点:

          1. 引用类型的属性被所有实例共享
          1. 在创建 Child 的实例时,不能向 Parent 传参
        • 二、借用构造函数(经典继承)

        • 优点:

          1. 避免了引用类型的属性被所有实例共享
          1. 可以在 Child 中向 Parent 传参
        • 缺点:

        最后

        自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

        深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

        因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

        img

        既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

        如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

        由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

        • 缺点:

        最后

        自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

        深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

        因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

        [外链图片转存中…(img-Qtnb6BZ6-1715548665039)]

        [外链图片转存中…(img-fE5UpdBQ-1715548665040)]

        [外链图片转存中…(img-pOMaN0GK-1715548665040)]

        既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

        如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

        由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

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

      抵扣说明:

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

      余额充值