zoukankan      html  css  js  c++  java
  • 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》
     
  • 相关阅读:
    Fluent动网格【8】:网格节点运动案例
    Fluent动网格【7】:网格节点运动
    Fluent动网格【6】:部件变形案例
    Fluent动网格【5】:部件变形
    Fluent动网格【4】:DEFINE_CG_MOTION宏实例
    Fluent动网格【3】:DEFINE_CG_MOTION宏
    Fluent动网格【1】:概述
    Fluent动网格【2】:Profile文件
    JavaScript系列--浅析原型链与继承
    简单说说JavaScript的Generator 实现(ES6)
  • 原文地址:https://www.cnblogs.com/goforxiaobo/p/12585359.html
Copyright © 2011-2022 走看看