zoukankan      html  css  js  c++  java
  • JavaScript 基础知识

    8.JavaScript 基础知识

    一、基础

    1、如何理解闭包?

    • 1)定义: 闭包就是能够读取其他函数内部变量的函数。简单说来,可以理解把闭包理解为“定义在一个函数内部的函数”

        function f1() {
          var n = 999;
          function f2() { console.log(n); }
          return f2;
        }
      
        var result = f1();
        result(); // 999
      
        //1)上述代码中的 f2 函数就是一个闭包。
        //2)由于链式作用域的原因,f2 可以访问 f1内定义的变量,反之则不行
        //3)把f2作为返回值,就可以在f1外部读取它的内部变量。
      
    • 2)闭包的用途:

      • 可以读取函数内部的变量。

      • 让这些变量始终保存在内存中。

          function f1() {
            var n = 999;
            nAdd = function () { n += 1 }
            function f2() { console.log(n) }
            return f2;
          }
        
          var result = f1();
          result(); // 999
          nAdd();
          result(); // 1000
        
          //原因:f1中的局部变量n 一直在内存中,并没有在f1调用后被自动清除。
          //因为f1是f2的父函数,而f2被赋给了一个全局变量,导致f2始终在内存中,而f2的存在依赖f1,因此f1也始终在内存中,最终都不会再调用结束被垃圾回收机制回收。
          //此处注意,nAdd也是一个闭包,它被挂载在全局变量下。
        
    • 3)使用闭包注意点:

      • 不能滥用闭包,会造成性能问题,IE中可能导致内存泄漏。解决办法是在退出函数之前,将不用的局部变量全部删除。
      • 如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

    2、this 的用法

    • 定义: this 是JavaScript 语言的一个关键字,它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内部使用。

    • 简单来讲:this 就是函数运行时所在的环境对象,即谁调用函数就指向谁。

    • 案例:

        // 1)this 代表全局对象,因为test 调用时挂载在全局对象下,故this代表全局对象
        var x = 1;
        function test() { console.log(this.x); }
        test(); //1
      
        // 2)对象方法调用, 此时this指向 obj,因为调用时是obj 在调用
        function test() { console.log(this.x); }
        var obj = {}
        obj.x = 1;
        obj.m = test;
        obj.m(); // 1
      
        // 3)构造函数调用, new时生成一个新对象,此时this就指向新对象
        var x = 2;
        function test() { this.x = 1; }
        var obj = new test();// this会指向新对象,不会指向全局对象
        console.log(x);  // 2
      
    • apply调用: (apply 是函数的一个方法,作用是改变函数的调用对象)

        用法:apply(thisObj, [args]); // [args] 是一个数组或类数组,是一个参数列表
        
        //示例如下:
        var x = 0;
        function test() { console.log(this.x); }
        var obj = {};
        obj.x = 1;
        obj.m = test;
      
        //apply无参,则代表指向全局对象
        obj.m.apply()// 0 
      
        //指定绑定this到obj上
        obj.m.apply(obj) //1
      
    • call调用改变this

      用法: call(thisObj, arg1, arg2, arg3, arg4);
      
      //示例代码:
      var name = "Jerry";
      var obj = { name: "Tom" };
      function sayName() {
        return this.name;
      }
      
      console.log(sayName.call(this));//Jerry
      console.log(sayName.call(obj));//Tom
      
      

    3、比较typeof 与 instanceof

    • 相同点:JS中 typeofinstanceof 常用来判断一个变量是否为空,或者什么类型的

    1)typeof 的用法:

    • 定义和用法:typeof返回值是一个字符串,用来说明变量的数据类型。

        var a = 1;
        typeof a // "number"
      
    • 细节:

      - typeof 一般只能返回:number boolean string function object undefined
      - 对于Array, null 等特殊对象,使用 typeof 一律返回 object,这正是它的局限性。
      
      

    2)instanceof的用法:

    • 定义:instanceof用于判断一个变量是否属于某个对象的实例。

        var a = new Array();
        console.log(a instanceof Array); //true
        console.log(a instanceof Object);// true,因为 Array 是 Object 的子类
      
        function test() { }
        var a = new test();
        console.log(a instanceof test); //true
      

    4、JS 中面向对象中继承实现

    1)使用prototype方式

      //继承方式,原型链形式,将方法挂载在 prototype 对象上
      function teacher(name) { this.name = name; }
      teacher.prototype.sayName = function () { console.log("name is" + this.name) }
      var teacher1 = new teacher("xiaoming");
      teacher1.sayName();
    
      //子类继承父类
      function student(name) { this.name = name; }
      student.prototype = new teacher();
      var student1 = new student("xiaohong");
      student1.sayName();
    

    2)使用 call() / apply() 方式

      function teacher(name, age) {
        this.name = name;
        this.age = age;
        this.sayHi = function () { console.log('Name:' + name + ", Age:" + age) };
      }
    
      function student() {
        var args = arguments;
        teacher.call(this, args[0], args[1]);
      }
    
      var teacher1 = new teacher('xiaoming', 30);
      teacher1.sayHi();
    
      var student1 = new student('xiaolan', 10);
      student1.sayHi();
    
    

    3)混合方法(prototype, call / apply

      function teacher(name, age) {
        this.name = name;
        this.age = age;
      }
    
      teacher.prototype.sayName = function () { onsole.log('name:' + this.name); }
      teacher.prototype.sayAge = function () { console.log('age:' + this.age); }
    
      function student() {
        var args = arguments;
        teacher.call(this, args[0], args[1]);
      }
    
      student.prototype = new teacher();
      var student1 = new student('xiaolin', 23);
      student1.sayName();
      student1.sayAge();
    

    5、JS 中的强制类型转换

    (1)显式转换

      var a = "42";
      var b = Number( a );
      a; // "42"
      b; // 42 -- 是个数字!
    

    (2)隐式转换

      var a = "42";
      var b = a * 1; // "42" 隐式转型成 42 
      a; // "42"
      b; // 42 -- 是个数字!
    

    6、JS 中的相等性

    • (1)严格比较 (如===)在不允许强制转型的情况下检查两个值是否相等

    • (2)抽象比较 (如==)在允许强制转型的情况下检查两个值是否相等

        var a = "42";
        var b = 42;
        a == b; // true
        a === b; // false
      

    7、"use strict"的作用是什么?

    说明: use strict出现在JS代码的顶部,可以帮助你写出更安全的JS代码。如果你错误的创建了全局变量,他会抛出错误的方式来警告你

    • 例如:如下代码因为x 没有被定义,并使用了全局作用域中的某个值对其进行赋值,加了 use strict 后就会报错。

        function doSomething(val) {
          "use strict"; 
          x = val + 10;
        }
      
    • 将变量声明到函数内部,严格模式下不会报错,如下:

        function doSomething(val) {
        "use strict"; 
        var x = val + 10;
        }
      

    8、null 和 undefined

    首先声明: 他们都是JS的两种类型。

    • 尚未初始化:undefined

    • 空值:null

    • 注意:nullundefined 是两个不同的对象,如下:

        null == undefined // true
        null === undefined // false
      

    9、delete 操作符

    • 说明:delete 操作符,只适用于删除对象的属性

        var a = {b:1}
        delete a.b;
        console.log(a) //object {}
      
    • 如果想要删除对象:

        a = null;
      
    • delete 删除变量不可行

      var name = 'lily';
      delete name;
      console.log(name); //lily
      
    • delete 删除不了原型链中的变量

      fun.prototype.age = 18;
      delete obj.age;
      console.log(obj.age) //18
      

    10、JavaScript 创建对象的几种方法

    • 对象字面量法:

        var obj = {}
      
    • 工厂模式:

      function Person(name, age) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.say = function () { console.log(name); }
        return o;
      }
      
    • 构造函数法:

        //1 直接new Object 对象
        var obj = new Object();
      
        //构造函数
        function Person(name, age) {
          this.name = name;
          this.age = age;
          this.say = function () { console.log(name); }
        }
        var person = new Person('hello', 18);
      
    • 原型模式:

      //实现方法与属性共享,可以动态添加对象的属性和方法。但是没法创建实例自己的属性和方法,也没办法传递参数
      function Person() {
        Person.prototype.name = 'jerry';
        Person.prototype.say = function () { console.log(this.name) }
        Person.prototype.friends = ['friend1'];
      }
      
      var person = new Person();
      
    • 构造函数和原型结合:

      function Person(name, age) {
        this.name = name;
        this.age = age;
      }
      Person.prototype.say = function () { console.log(this.name) }
      
      var person = new Person('hello');
      

    二、Web 性能相关

    1、前端性能优化的方法

    • (1)减少 http 请求次数:JS、CSS 源码压缩、图片大小控制合适、网页Gzip CDN 托管,data 缓存,图片服务器等。
    • (2)前端JS+数据,减少由HTML标签导致的宽带浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数。
    • (3)用innerHTML代替DOM操作,优化JavaScript性能。
    • (4)当需要设置的样式很多时,设置className 而不是直接操作style。
    • (5)少用全局变量、缓存DOM节点查找结果。减少IO读取操作。
    • (6)避免使用CSS 表达式,又称 动态属性(Dynamic properties)
    • (7)图片预加载,将样式放到顶部,将脚本放在底部,加上时间戳。
    • (8)避免在页面的主体布局中使用table,table要等其中的内容完全下载之后才会显示出来,显示要比 DIV+CSS布局要慢。
    • (9)CSS Sprites:合并 CSS图片,减少请求数的又一个好办法。
    • (10)LazyLoad Images 在页面刚加载的时候可以只加载第一屏,当用户继续往后滚屏的时候才加载后续图片。
    • (11)减少cookie传输,请求带大cookie会严重影响数据传输,对于静态资源如CSS、Script 传输cookie没有意义。

    网站优化的思路:

    对普通的网站有一个统一的思路,就是尽量向前端优化、减少数据库操作、减少磁盘IO。向前端优化指的是,在不影响功能和体验的情况下,
    能在浏览器执行的不要在服务端执行,能在缓存服务器上直接返回的不要到应用服务器,程序能直接取得的结果不要到外部取得,
    本机内能取得的数据不要到远程取,内存能取到的不要到磁盘取,缓存中有的不要去数据库查询。
    减少数据库操作指减少更新次数、缓存结果减少查询次数、将数据库执行的操作尽可能的让你的程序完成(例如join查询),减少磁盘IO指尽量不使用文件系统作为缓存、减少读写文件次数等。
    程序优化永远要优化慢的部分,换语言是无法“优化”的。
    

    2、垃圾回收机制方式及内存管理

    • 1)定义和用法: 垃圾回收机制(GC:Garbage Collection),执行环境负责管理代码执行过程中使用的内存。

    • 2)原理: 垃圾收集器会定期(周期性)找出那些不再继续使用的变量,然后释放其内存,但是这个过程不是实时的,因为开销比较大,所以GC会按固定时间间隔周期执行。

        function fn1() {
          var obj = { name: "jerry", age: 10 };
        }
      
        function fn2() {
          var obj = { name: "jerry", age: 10 };
          return obj;
        }
      
        var a = fn1();// fn1 方法中的局部变量会被GC回收
        var b = fn2();// fn2 中的局部变量不会被GC回收,因为 obj 被挂载在了全局变量上
      
    • 3)垃圾回收策略: 标记清除(较为常用)和引用计数

      • 标记清除:

        定义和用法:当变量进入环境时,将变量标记"进入环境",当变量离开环境时,标记为:"离开环境"。
        某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。
        到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。
        
      • 引用计数:

        定义和用法:引用计数是跟踪记录每个值被引用的次数。
        基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。
        
    • 4)内存管理

        1、什么时候触发垃圾回收?
      
          垃圾回收器周期性运行,如果分配的内存非常多,那么回收工作也会很艰巨,确定垃圾回收时间间隔就变成了一个值得思考的问题。
          IE6的垃圾回收是根据内存分配量运行的,当环境中的变量,对象,字符串达到一定数量时触发垃圾回收。垃圾回收器一直处于工作状态,严重影响浏览器性能。
          IE7中,垃圾回收器会根据内存分配量与程序占用内存的比例进行动态调整,开始回收工作。
      
        2、合理的GC方案:(1)、遍历所有可访问的对象; (2)、回收已不可访问的对象。
        3、GC缺陷:(1)、停止响应其他操作;
        4、GC优化策略:(1)、分代回收(Generation GC);(2)、增量GC
      

    三、Web 安全

    必考:什么是跨域? 跨域请求的方法有哪些?

    1、什么是跨域?

    • 定义: 由于浏览器同源策略,凡是发送请求的URL 协议域名端口三者之间任意一与前页面地址不同则为跨域。

    • 存在跨域的情况

      - 网络协议不同,如http协议访问https协议
      - 端口不同,如80端口访问8080端口
      - 域名不同,如taobao.com 访问 baidu.com
      - 子域名不同,如 abc.baidu.com 访问 def.baidu.com
      - 域名和域名对应ip,如www.a.com 访问 10.0.0.8
      

    2、跨域请求资源的方法

    • (1)proxy代理

      定义和用法:proxy代理用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求结果传回前端。
      实现方法:通过nginx 代理。
      
      注意点:1、如果你代理的是https协议的请求,那么你的proxy首先需要信任该证书(尤其是自定义证书)或者忽略证书检查,否则你的请求无法成功。
      
    • (2)CORS 【Cross-Origin Resource Sharing】

      • 定义和用法:是现代浏览器支持跨域资源请求的一种最常用的方式。

      • 使用方法: 使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作。如下:

        res.writeHead(200, {
            "Content-Type": "text/html; charset=UTF-8",
            "Access-Control-Allow-Origin":'http://localhost',
            'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
            'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type'
        });
        
    • (3)jsonp

      • 定义和用法:通过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行。

      • 特点:通过动态创建script来读取他域的动态资源,获取的数据一般为json格式。

          <script>
              function testjsonp(data) {
                console.log(data.name); // 获取返回的结果
              }
          </script>
          <script>
              var _script = document.createElement('script');
              _script.type = "text/javascript";
              _script.src = "http://localhost:8888/jsonp?callback=testjsonp";
              document.head.appendChild(_script);
          </script>
        
      • 缺点:1、这种方式无法发送post请求。2、另外要确定jsonp的请求是否失败并不容易,大多数框架实现都是结合超时时间来判定的。

    四、练习题

    1、JavaScript 当中,如果检测一个变量时一个String 类型?

      typeof(obj) === "string"
      typeof obj === "string"
      obj.constructor === String
    

    2、请写出3个使用this的典型应用

    • 在HTML 元素事件属性上使用

        <input type="button" onclick="showInfo(this);" value=”点击一下”/>
      
    • 构造函数

        function Animal(name, color) {
          this.name = name;
          this.color = color;
        }
      
    • apply() / call()求数组最值

        var  numbers = [5, 458 , 120 , -215 ]; 
        var  maxInNumbers = Math.max.apply(this, numbers);  
        console.log(maxInNumbers);  // 458
        var maxInNumbers = Math.max.call(this,5, 458 , 120 , -215); 
        console.log(maxInNumbers);  // 458
      

    3、请用JS 去除字符串中的空格

    • 方法一:使用replace正则匹配的方法

        去除所有空格: str = str.replace(/s*/g,"");
        去除两头空格: str = str.replace(/^s*|s*$/g,"");
        去除左空格: str = str.replace( /^s*/, "");
        去除右空格: str = str.replace(/(s*$)/g, "");
      
    • 方法二:使用str.trim()方法

        var str = "   xiao  ming   "; 
        var str2 = str.trim(); // xiao ming,str.trim() 的局限性,无法去除中间的空格
      

    4、如何获取浏览器URL中查询字符串中的参数

    • 思路:使用 window.location.href,通过 split 方法根据 & 进行分割获取。

        function showWindowHref() {
          var sHref = window.location.href;
          var args = sHref.split('?');
          if (args[0] == sHref) { return ""; }
      
          var arr = args[1].split('&');
          var obj = {};
          for (var i = 0; i < arr.length; i++) {
            var arg = arr[i].split('=');
            obj[arg[0]] = arg[1];
          }
          return obj;
        }
        var href = showWindowHref(); // obj
        console.log(href['name']); // xiaoming
      

    5、解释事件冒泡以及如何阻止它?

    • 定义:事件冒泡是指嵌套最深的元素触发一个事件,然后这个事件顺着嵌套顺序在父元素上触发。
    • 如何防止:使用 event.cancelBubbleevent.stopPropagation() (低于IE9)

    6、如何检查一个数字是否为正数?

    • 思路:对1进行取模,看是否有余数。

        function isInit(num) { return num % 1 === 0; }
      
        console.log(isInit(4));//true
        console.log(isInit(12.2));//false
        console.log(isInit(0.3));//false
      

    7、解释JS "undefined" 和 "not defined"之间的区别

    • not defined: 如果你试图使用一个不存在且尚未声明的变量,JS将报错:“Uncaught ReferenceError: xxx is not defined”
    • undefined表示变量未赋值
    aaa // Uncaught ReferenceError: aaa is not defined
    typeof aaa// "undefined" 
    
    • 当我们试图访问一个被声明但未被定义的变量时,会出现undefined错误
      var x; // 声明
      typeof x === 'undefined' // true 
    

    8、匿名函数和命名函数有什么区别?

      //(1)赋给变量foo 的匿名函数
      var foo = function () { }
      //(2)赋给变量x 的命名函数
      var x = function bar() { }
    

    9、如何在JS中创建私有变量?

    • 将变量创建成局部变量,就是这个函数被调用,也无法在函数之外访问这个变量

        function func() { var priv = "secret code"; }
        console.log(priv)// 抛异常 Uncaught ReferenceError: priv is not defined
      
    • 要访问私有变量,需要借助闭包函数

        //要想访问这个私有变量,可以通过闭包的方式,将闭包函数返回
        function func() {
          var priv = "secret code";
          return function () { return priv; }
        }
      
        var getPriv = func();
        getPriv();//"secret code"
      

    10、以下代码输出什么?

    0.1 + 0.2 === 0.3 //false
    //结果为false,这是由浮点数内部表示导致的。0.1+0.2并不刚好等于0.3,实际结果为 0.30000000000000004
    

    11、如何向Array 对象添加自定义方法,让下面的代码可以运行?

      var arr = [1, 2, 3, 4, 5];
      var avg = arr.average();
      console.log(avg);
    

    思路: 用原型 prototype,由于JS的每个对象都链接到另一个对象(也就是对象的原型),并继承原型对象的方法,你可以跟踪每个对象的原型链,
    直到到达没有原型的null对象,我们需要通过修改Array原型来向全局Array对象添加方法。

      Array.prototype.average = function () {
        //计算sum 的值
        var sum = this.reduce(function (prev, cur) { return prev + cur; });
        //将sum除以元素个数并返回
        return sum / this.length;
      }
    
      var arr = [1, 2, 3, 4, 5];
      var avg = arr.average();
      console.log(avg);//3
    

    12、什么是window对象?什么是document对象?

    window 对象代表浏览器中打开的一个窗口。
    document对象代表整个HTML文档。实际上,document对象是window对象的一个属性。
    

    13、AMD(Modules/Asynchronous-Definition) 和 CMD (Common Module Definition)规范区别?

    • 说明: AMDRequireJS 在推广过程中对模块定义的规范化产出。CMDSeaJS 在推广过程中对模块定义的规范化产出。

    • 区别:

      • 对于依赖的模块,AMD 是提前执行,CMD是延迟执行。不过RequireJS2.0 开始,也改成延迟执行。

      • CMD 推崇依赖就近,AMD 推崇依赖强制。

      • AMD 的 API 默认是一个当多个用,CMD 的API 严格区分,推崇职责单一。

          // CMD
          define(function(require, exports, module) {
              var a = require('./a')
              a.doSomething()
              // 此处略去 100 行
              var b = require('./b') // 依赖可以就近书写
              b.doSomething()
          })
          // AMD 默认推荐
          define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
              a.doSomething();
              // 此处略去 100 行
              b.doSomething();
          })
        

    14、JS延迟加载方式有哪些?

    • JS 的延迟加载,有助于提高页面的加载速度。
      defer 和 async 动态创建DOM方式(用的最多),按需异步载入JS。
        defer:延迟脚本。立即下载,但延迟执行(延迟到整个页面都接卸完毕后再运行),按照脚本的先后顺序执行。
        async:异步脚本。下载完立即执行,但不能保证按脚本出现的先后顺序执行。
    

    15、下面代码输出什么?

      var y = 1;
      if (function f(){}) {
          y += typeof f;
      }
      console.log(y); // 1undefined
    
    

    16、写一个 mul 函数,使用方法如下:

    console.log(mul(2)(3)(4)); // output : 24 
    console.log(mul(4)(3)(4)); // output : 48
    

    答案:

    //使用嵌套闭包即可
    function mul(x) {
      return function (y) {
        return function (x) {
          return x * y * z;
        }
      }
    }
    

    17、JavaScript 怎么清空数组

    var arrayList = ['a','b','c','d','e','f'];
    //方法1:
    arrayList = [];
    //方法2:
    arrayList.length = 0;
    //方法3:
    arrayList.splice(0, arrayList.length);
    

    18、怎么判断一个object是否是数组(array)?

    • 方法一:使用 Object.prototype.toString 来判断

        function isArray(obj){
            return Object.prototype.toString.call( obj ) === '[object Array]';
        }
      
    • 方法二:使用原型链

        function isArray(obj){
            return obj.__proto__ === Array.prototype;
        }
      
    • 方法三:利用JQuery

        function isArray(obj){
            return $.isArray(obj)
        }
      

    19、下面代码输出什么?

      var output = (function (x) {
        delete x;
        return x;
      })(0)
    
      console.log(output);//输出是 0。 delete 操作符是将object的属性删去的操作。但是这里的 x 是并不是对象的属性, delete 操作符并不能作用。
    

    20、下面代码输出什么?

    var Employee = { company: 'xyz' }
    
    var emp1 = Object.create(Employee);
    delete emp1.company;
    console.log(emp1.company); // xyz
    
    //原因是 这里的 emp1 通过 prototype 继承了 Employee 的company。emp1 并没有自己的 company属性,此处delete 无效。
    

    21、什么是undefined x 1?

    说明:当我们使用delete 删除一个数组中的元素,这个元素的位置就会变成一个占位符,打印出来就是 undefined x 1

    var trees = ["redwood","bay","cedar","oak","maple"];
    delete trees[3];
    console.log(trees); // ["redwood", "bay", "cedar", empty, "maple"]
    console.log(trees[3]); //undefined
    

    22、下面代码输出什么?

    var trees = ["xyz","xxxx","test","ryan","apple"];
    delete trees[3];
      
    console.log(trees.length);//5 delete 操作符删完数组元素后,并不影响数组长度
    

    23、下面代码输出什么?

    var bar = true;
    console.log(bar + 0);//1
    console.log(bar + "xyz");//truexyz  
    console.log(bar + true);  //2
    console.log(bar + false); //1
    

    可以对照如下操作:

    Number + Number -> 加法
    Boolean + Number -> 加法
    Boolean + Boolean -> 加法
    Number + String -> 连接
    String + Boolean -> 连接
    String + String -> 连接
    

    24、下面代码输出什么?

    var z = 1, y = z = typeof y;
    console.log(y);  
    

    上面代码等价于

    var z = 1
    z = typeof y;
    var y = z;
    console.log(y);// undefined
    

    25、下面代码输出什么?

    var foo = function bar(){ return 12; };
    typeof bar(); //抛异常, Uncaught ReferenceError: bar is not defined
    

    如下修改不会抛异常

    var bar = function(){ return 12; };
    typeof bar();
    //或者
    function bar(){ return 12; };
    typeof bar();
    

    26、如下两种函数声明有什么区别?

    //foo的定义是在运行时,这种声明方式会有变量提升问题
    var foo = function(){}
    
    function bar(){}
    

    如下:使用匿名方式声明,定义的变量会导致变量提升,所以上述代码执行顺序如下

    // foo bar的定义位置被提升
    function bar(){}; 
    var foo;
    
    console.log(foo)// undefined
    
    foo = function(){}; 
    

    27、如下代码输出什么?

    var salary = "1000$";
    
    (function () {
        console.log("Original salary was " + salary);
        var salary = "5000$";
        console.log("My New Salary " + salary);
    })();
    
    // 答案:  
    //Original salary was undefined
    // My New Salary 5000$
    

    考察变量提升,上述函数中的 console.log("Original salary was " + salary); 这行代码,先使用了 salary 这个变量,函数内部会有变量提升问题,等价于如下:

      var salary ;
      console.log("Original salary was " + salary);
    

    28、如果我使用JS的“关联数组”,我们怎么计算“关联数组”的长度?

    var counterArray = {
        A : 3,
        B : 4
    };
    counterArray["C"] = 1;
    
    //答案:直接计算key 的数量就可以了
    Object.keys(counterArray).length // Output 3
    

    29、JavaScript 中有哪些弹出框?

    Alert、Confirm 、Prompt
    

    30、Void(0) 怎么用?

    Void(0)用于防止页面刷新,并在调用时传递参数“zero”。
    Void(0)用于调用另一种方法而不刷新页面。
    

    31、如何创建通用对象?

    var I = new object();
    
  • 相关阅读:
    基于单片机定时器---年月日时分秒的算法
    按位查询算法---基于Perimiter Sensor
    MFC File crc 计算
    二叉树的层次遍历

    动态规划
    贪心算法 动态规划
    爱信息图床测试
    前端小白的个人习惯和笔记(一)
    过年了,是不是应该写点代码祝福别人
  • 原文地址:https://www.cnblogs.com/vpersie2008/p/14731112.html
Copyright © 2011-2022 走看看