• JavaScript基础知识题


    ①ES6新特性?学习地址 学习地址2

    ECMAScript 6(ES6) 目前基本成为业界标准,它的普及速度比 ES5 要快很多,主要原因是现代浏览器对 ES6 的支持相当迅速,尤其是 Chrome 和 Firefox 浏览器,已经支持 ES6 中绝大多数的特性。

    1.不一样的变量声明:const和let

    ES6推荐使用let声明局部变量,相比之前的var(无论声明在何处,都会被视为声明在函数的最顶部)

    let表示声明变量,而const表示声明常量,两者都为块级作用域;const 声明的变量都会被认为是常量,意思就是它的值被设置完成后就不能再修改了。

    如果const的是一个对象,对象所包含的值是可以被修改的。抽象一点儿说,就是对象所指向的地址没有变就行。

    有几个点需要注意:

    • let 关键词声明的变量不具备变量提升(hoisting)特性
    • let 和 const 声明只在最靠近的一个块中(花括号内)有效
    • 当使用常量 const 声明时,请使用大写变量,如:CAPITAL_CASING
    • const 在声明时必须被赋值

    2.模板字符串

    在ES6之前,我们往往这么处理模板字符串:
    通过“”和“+”来构建模板

    而对ES6来说

    ①基本的字符串格式化。将表达式嵌入字符串中进行拼接。用${}来界定;

    ②ES6反引号(``)直接搞定;

    3.箭头函数(Arrow Functions)

    ES6 中,箭头函数就是函数的一种简写形式,使用括号包裹参数,跟随一个 =>,紧接着是函数体;

    箭头函数最直观的三个特点。

    • 不需要 function 关键字来创建函数
    • 省略 return 关键字
    • 继承当前上下文的 this 关键字
    细节:当你的函数有且仅有一个参数的时候,是可以省略掉括号的。当你函数返回有且仅有一个表达式的时候可以省略{} 和 return;  

    4. 函数的参数默认值

    在ES6之前,我们往往这样定义参数的默认值:

    // ES6之前,当未传入参数时,text = 'default';
    function printText(text) {
        text = text || 'default';
        console.log(text);
    }
    
    // ES6;
    function printText(text = 'default') {
        console.log(text);
    }
    
    printText('hello'); // hello
    printText();// default

    5.Spread / Rest 操作符 

    Spread / Rest 操作符指的是 ...,具体是 Spread 还是 Rest 需要看上下文语境。

    当被用于迭代器中时,它是一个 Spread 操作符:

    function foo(x,y,z) {
      console.log(x,y,z);
    }
     
    let arr = [1,2,3];
    foo(...arr); // 1 2 3

    当被用于函数传参时,是一个 Rest 操作符:当被用于函数传参时,是一个 Rest 操作符:

    function foo(...args) {
      console.log(args);
    }
    foo( 1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]

    6.二进制和八进制字面量

    ES6 支持二进制和八进制的字面量,通过在数字前面添加 0o 或者0O 即可将其转换为八进制值:

    let oValue = 0o10;
    console.log(oValue); // 8
     
    let bValue = 0b10; // 二进制使用 `0b` 或者 `0B`
    console.log(bValue); // 2

    7.对象和数组解构

    // 对象
    const student = {
        name: 'Sam',
        age: 22,
        sex: '男'
    }
    // 数组
    // const student = ['Sam', 22, '男'];
    
    // ES5;
    const name = student.name;
    const age = student.age;
    const sex = student.sex;
    console.log(name + ' --- ' + age + ' --- ' + sex);
    
    // ES6
    const { name, age, sex } = student;
    console.log(name + ' --- ' + age + ' --- ' + sex);

    8.对象超类

    ES6 允许在对象中使用 super 方法:

    var parent = {
      foo() {
        console.log("Hello from the Parent");
      }
    }
     
    var child = {
      foo() {
        super.foo();
        console.log("Hello from the Child");
      }
    }
     
    Object.setPrototypeOf(child, parent);
    child.foo(); // Hello from the Parent
                 // Hello from the Child

    9.for...of 和 for...in

    for...of 用于遍历一个迭代器,如数组:

    let letters = ['a', 'b', 'c'];
    letters.size = 3;
    for (let letter of letters) {
      console.log(letter);
    }
    // 结果: a, b, c

    for...in 用来遍历对象中的属性:

     let stus = ["Sam", "22", "男"];
     for (let stu in stus) {
       console.log(stus[stu]);
      }
    // 结果: Sam, 22, 男

    10.ES6中的类

    ES6 中支持 class 语法,不过,ES6的class不是新的对象继承模型,它只是原型链的语法糖表现形式。

    函数中使用 static 关键词定义构造函数的的方法和属性:

    class Student {
      constructor() {
        console.log("I'm a student.");
      }
     
      study() {
        console.log('study!');
      }
     
      static read() {
        console.log("Reading Now.");
      }
    }
     
    console.log(typeof Student); // function
    let stu = new Student(); // "I'm a student."
    stu.study(); // "study!"
    stu.read(); // "Reading Now."

    类中的继承和超集:

    class Phone {
      constructor() {
        console.log("I'm a phone.");
      }
    }
     
    class MI extends Phone {
      constructor() {
        super();
        console.log("I'm a phone designed by xiaomi");
      }
    }
     
    let mi8 = new MI();

    extends 允许一个子类继承父类,需要注意的是,子类的constructor 函数中需要执行 super() 函数。

    当然,你也可以在子类方法中调用父类的方法,如super.parentMethodName()。
    在 这里 阅读更多关于类的介绍。

    有几点值得注意的是:

    • 类的声明不会提升(hoisting),如果你要使用某个 Class,那你必须在使用之前定义它,否则会抛出一个 ReferenceError 的错误
    • 在类中定义函数不需要使用 function 关键词
     

    ②简述JavaScript中的作用域链?学习地址

    由于js存在全局变量和局部变量,在调用一个变量是,会对他的作用域链进行查找,如果函数内部定义了这个变量,那么取该变量的值,如果没有,那么向上一层查找,如果找到了,就获取这个值,如果还没找到,继续往上层查找,直到找到位置,如果找到最后也没找到,那么该变量的值为undefined。

     关于变量作用域的知识,相信学习JavaScript的朋友们一定早已经接触过,这里简单列举:  

    • JavaScript中变量是以对象属性的形式存在的:全局变量是全局对象的属性;局部变量是声明上下文对象的属性。(声明上下文对象是一个对用户不可见的内部实现,无法被引用,每当函数调用便创建这个对象以存放局部变量)
    • JavaScript虽然是解释型语言,但也存在预处理过程,其中便包含了声明提前。JavaScript解释器运行前,会先将整个程序中的变量声明(包括函数)提前到作用域顶部执行。所以在程序中变量的使用语句可以出现在声明语句之前。
    • JavaScript中没有块级作用域(像C语言那样用方括号{}划分作用域),而是使用函数作用域;
    • 不在任何函数体内声明的变量为全局变量,拥有全局作用域,可以在程序的任何位置被访问;而在函数内声明的变量(包括函数的参数)为局部变量,拥有局部作用域,只在函数内部有定义;
    • 若局部变量与全局变量重名,局部变量优先级高,可以遮盖全局变量;
    • 局部作用域可以相互嵌套(因为函数可以嵌套)

    而作用域链的概念,接触过的人就没那么多了。其实作用域链很好理解,上方第一条已经明确了,JavaScript中变量是以对象属性的形式存在的,而作用域链其实就是这些对象组成的一个链表。全局变量是全局对象的属性,局部变量是声明上下文对象的属性。这些对象按从内向外的顺序链接,链尾当然就是全局对象。当函数运行中需要查找某一个变量的时候,就会沿着作用域链依次查询每个对象是否拥有与该变量同名的属性,如果存在则直接使用;若整条链上都不存在这个属性,便抛出ReferenceError。 在函数定义的时候,便创建了作用域链,链上的对象顺序便确定下来,当函数被调用,创建相应的对象添加到作用域链中,作用域链会随着函数的定义调用而更新。在嵌套函数中更是如此,每次调用外部函数时,内部函数又会重新定义,随之带来的就是作用域链的相应变化。关于作用域链的数量,可以用树来比喻,全局对象是根节点,函数的嵌套代表着树节点的层级关系,那么一个程序中作用域链的数量等于对应树中叶子节点的数量。 

    ③简述JS中创建自定义对象的方式?学习地址

    自定义对象,指由用户创建的对象,兼容性问题要由编写者考虑。

    1.对象直接量

    var obj = {
      webName: "蚂蚁部落",
      address: "青岛市南区"
    }

    对象直接量是由键值对列表组成,列表包含在大括号中,属性名称和属性值由冒号分隔,每一个键值对之间是用逗号分隔,属性值可以是任何类型。

    2.工厂模式

    工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程。考虑到在ECMAScript种无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节,如下面例子所示:

    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=new createPerson("Nicholas",29,"Software Engineer");
    var person2=new createPerson("Greg",27,"Doctor");

    函数createPerson()能够根据接受的参数来构建一个包含所有必要信息的Person对象。可以无数次地调用这个函数,而每次它都会返回一个包含三个属性一个方法的对象。工厂模式虽然解决了创建多个类似对象的问题,但是却没有解决对象识别的问题。随之来的就是构造函数模式。

    3.构造函数模式 new object() 

    var obj = new object();

    obj.webName = "蚂蚁部落"; 

    obj.address = "青岛市南区"; 

    以上代码采用构造函数方式创建对象obj,为其添加两个属性并赋值。

    4.原型模式

    在js中可以像“后端”一样使用原型模式创建对象。在调式的过程中,发现原型模式的确可以创建对象,而且相当于引用类型,也就是说,比如通过它来创建两个对象,那么这两个对象创建完后,若其中一个对象改变了原型模式中的属性的值,那么另一个对象也会受到影响,这也就是说不管创建多少个对象,那么这些对象都指向同一个存储空间,这也就是原型模式的一个优势,避免了资源的浪费,因为所有通过它创建的对象,都指向同一个内存空间。

    5.组合使用构造函数模式和原型模式

     

    ④this关键字的作用是什么?学习地址

    笼统的说,关键字this指向当前对象。比如,

    顶级代码中的this指向全局对象;

    在指定元素事件的时候,this指定当前发生事件的元素对象;

    对于嵌套函数,如果嵌套函数作为方法被调用,其this指向调用它的对象;

    如果作为函数调用,this是全局对象或者为undefined(严格模式下)。

     

    ⑤简要描述JS中的匿名函数?学习地址

    匿名函数常用于定义不需要重复使用的函数,用完即释放。

    用小括号括上,并在后面加一组小括号用来自调。

    匿名函数的基本形式为(function(){...})();

    前面的括号包含函数体,后面的括号就是给匿名函数传递参数并立即执行之。

    匿名函数的作用是避免全局变量的污染以及函数名的冲突。

    ⑥什么是正则表达式?JS中如何应用?

    正则表达式本身就是一个字符串,由一些普通字符和特殊字符组成,用以描述一种特定的字符规则的表达式。

    正则表达式常用于在一段文本中搜索、匹配或替换特定形式的文本。

    应用分为两种方式:

    1.结合String对象的replace、search和match方法,实现对字符串的替换查找和匹配。

    2.定义正则表达式对象,实现对字符串的复杂匹配操作。

     

    ⑦简述JS中定义函数的几种方式?学习地址

    1.函数语句:即使用function关键字显式定义函数。

       function f(x){

            return x+1; 

       }

    2.函数定义表达式,也称为"函数直接量"。

       var f = function(x){return x+1;} 

    3.使用Function()构造函数定义。(必须大写F)

    PS:如果一个函数是需要经常使用的函数就应该避免使用Function()构造函数来定义函数。Fuction()构造函数可以动态定义和编译函数,而function语句只能预编译函

    数,因此在每次调用使用Function()构造函数定义的函数时,javascript都要编译一次函数。学习地址

    ⑧简述arguments对象的作用?

    arguments可以访问函数的参数。即开发者在定义函数时,无需明确的为方法声明参数,也可以在方法体中使用arguments来访问参数。

    这是因为arguments是一种特殊的对象,在函数代码中,表示函数的参数数组。

    因此,可以通过使用arguments.length检测函数的参数个数,

    可以通过下标arguments[index]来访问某个参数。

    这样,可以用arguments对象判断传递给函数的参数个数并获取参数。适用于函数参数无法确定个数的情况。

     

    ⑨什么是逻辑短路?

    逻辑短路是对于逻辑运算而言,是指,仅计算逻辑表达式的一部分便能确定结果,而不是对整个表达式计算的现象。

    对于"&&"运算符,当第一个操作数为false时,将不会判断第二个操作数,因为结果一定是false。

    对于"||"运算符,当第一个操作数为true时,将不会判断第二个操作数,因为结果一定是true。

    ⑩解释一下JS中局部变量和全局变量的区别?

    全局变量拥有全局作用域,在JavaScript代码的任何地方都能访问;在函数内声明的变量只在函数体内有定义,即为局部变量,其作用域是局部性的。

    需要注意的是,在函数体内声明局部变量时,如果不用var关键字,则将声明全局变量。

    ⑪简述JS的数据类型?

    可分为基本类型和引用类型。

    五大基本类型:string 、number 、boolean 、以及两个原始值: null(空) 和 undefined(未定义)

            基本类型的访问是按值访问的,就是说你可以操作保存在变量中的实际的值。有如下特点:

    1. 基本数据类型的值是不可变的(我们不能给基本数据类型添加属性和方法);
    2. 基本数据类型的比较是值的比较(只有他们的值相等的时候才是相等的);
    3. 基本数据类型的变量是存放在栈里面的  

    引用类型(对象类型): Array 、Date 、Object 、RegExp 、Function

            对象是属性和方法的集合,也就是说引用数据类型可以拥有属性和方法,属性又可以包括基本数据类型和引用数据类型。有如下特点:
    1. 引用数据类型可以拥有属性和方法,且值是可变的;
    2. 引用数据类型的值是同时保存在栈内存和堆内存的对象;
     
     

    ⑫如何阻止表单提交?

    在 onsubmit 事件中返回 return false;调用  event.preventDefault();效果一样。

     
     
     
     
    Beautiful things don't ask for attention.美好的事物不要轻易惊扰。--来自2013年的《The Secret Life of Walter Mitty》
     
  • 相关阅读:
    fullCalendar改造计划之带农历节气节假日的万年历(转)
    Linked List Cycle
    Remove Nth Node From End of List
    Binary Tree Inorder Traversal
    Unique Binary Search Trees
    Binary Tree Level Order Traversal
    Binary Tree Level Order Traversal II
    Plus One
    Remove Duplicates from Sorted List
    Merge Two Sorted Lists
  • 原文地址:https://www.cnblogs.com/goforxiaobo/p/12585359.html
Copyright © 2020-2023  润新知