javaScript基础(二)

219 阅读7分钟

javaScript基础(二)

· Javascript作用链域?

  作用域:包括全局作用域和局部作用域。

      全局作用域: 最外层函数定义的变量拥有全局作用域。即对任何内部函数而言都可以访问。

      局部作用域: 一般只能在固定的代码片段可以访问,对于函数外部是无法访问的。(注意:在定义变量的时候一定要使用var命令。不然的话,就相当于声明了一个全部变量。)

  作用域链:当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。

· 谈谈This对象的理解。

  this设计的目的就是在函数体内部,指代函数当前的运行环境。

· eval是做什么的?

/** eval()方法:就像是一个完整的ECMAScript解析器,它只接受一个参数,即要执行的javascript(ECMAScript)字符串。如下例子 */

eval('console.log("hello")') // 相当于console.log('hello')

// 当调用eval()方法时,它会将传入的参数当作实际的ECMAScript语句来执行。

· 什么是window对象? 什么是document对象?

  window对象:是客户端浏览器对象模型的基类,是客户端JavaScript的全局对象。

  document对象:当浏览器加载文档后,会自动构建文档对象模型,把文档中每个元素都映射到一个数据集合中,然后以document进行访问。

· null,undefined的区别?

  null:特指对象的值未设置。

  undefined:表示已经声明了变量但未对其初始化。

· 写一个通用的事件侦听器函数。

    /**
    <div id="click-dom">点击测试
        <div id="stop-dom">冒泡</div>
    </div>
    <div>
        <a href="http:www.baidu.com" id="prevent-dom">阻止默认事件</a>
    </div>
    */
    
    /** 把所有方法封装到一个对象里面,充分考虑兼容写法 */
    var EventUtil = {
        // 添加DOM事件
        addEvent: function (element, type, handler) {
            if (element.addEventListener) { // DOM2级
                element.addEventListener(type, handler)
            } else if (element.attachEvent) {
                element.attachEvent('on' + type, handler)
            } else {
                element['on' + type] = handler
            }
        },
        
        // 删除DOM事件
        removeEvent: function (element, type, handler) {
            if (element.removeEventListener) { // DOM2级
                element.removeEventListener(type, handler)
            } else if (element.detachEvent) {
                element.detach('on' + type, handler)
            } else {
                element['on' + type] = null
            }
        },
        
        // 阻止冒泡事件
        stopPropagetion: function (ev) {
            if (ev.stopPropagation) {
                ev.stopPropagation()
            } else {
                ev.cancelBubble = true
            }
        },
        
        // 阻止默认事件
        preventDefault: function (e) {
            if (e.preventDefault) {
                e.preventDefault()
            } else {
                ev.returnValue = true
            }
        },
        
        // 获取事件源对象
        getTarget: function (ev) {
            return event.target || event.srcElement
        },
        
        // 获取事件对象
        getEvent: function (e) {
            var ev = e || window.event
            if (!ev) {
                var c = this.getEvent.caller
                while (c) {
                    ev = c.arguments[0]
                    if (ev && Event === ev.constructor) {
                        break
                    }
                    c = c.caller
                }
            }
            return ev
        }
    }
    var DOM = document.getElementById('click-dom')
    function handler () {
        console.log(this.innerHTML)
    }
    EventUtil.addEvent(DOM, 'click', handler)
    // EventUtil.removeEvent(DOM, 'click', handler)
    
    var DOM2 = document.getElementById('stop-dom')
    EventUtil.addEvent(DOM2, 'click', function (e) {
        console.log(12)
        EventUtil.stopPropagation(e)
    })
    
    var DOM3 = document.getElementById('prevent-dom')
    EventUtil.addEvent(DOM3, 'click', function (e) {
        EventUtil.preventDefault(e)
        console.log(EventUtil.getTarget(e))
        console.log(EventUtil.getEvent(e))
    })

· ['1', '2', '3'].map(parseInt) 答案是多少?

  答案:[1, NaN, NaN]

/** 
    解析--
    1. 执行map()方法会返回三个参数,item(数组中正在处理的元素)、index(数组中正在处理的当前位置的索引)、thisArr(map方法被调用的数组)三个参数。
    2. 执行parseInt(string, radix)方法会接收两个参数,string(必需,被解析的字符串)、radix(可选。表示解析的基数,改值介于2-36,如果为0默认10的基数来解析。如果小于2或大于36,则返回NaN)
    由于['1', '2', '3']执行map方法时,map会给parseInt传递item、index、thisArr(这个是可以忽略),因此最后会执行如下代码:
*/
parseInt('1', 0) // 由于parseInt第二个参数为0,所以默认以十进制解析字符串,返回1
parseInt('2', 1) // 由于基数小于2,所以返回NaN
parseInt('3', 2) // 当前的字符串时3,基数是2(要以二进制表示),而这是不合理的,所以返回NaN

· 关于事件,IE与火狐的事件机制有什么区别?如何阻止冒泡?

  事件流:触发点击事件的时候,会依次从外往内或者从内往外到达特定目标。

  冒泡流:从内往外到达特定目标。

  捕获流:从外往内到达特定目标。

  区别:IE的事件流是冒泡流,火狐支持冒泡流和捕获流。

  阻止冒泡:使用e.stopPropagation();IE使用的是e.canceBubble = true。

· 什么是闭包(closure),为什么要用它?

  闭包:就是能够读取其它函数内部变量的函数;也可以理解为一个函数内部嵌套另一个函数。

  闭包的特性:

        - 内部函数可以引用外层的参数和变量。

        - 参数和变量不会被垃圾回收机制回收。

  如下:

    function say667 () {
        var num = 666
        var sayFun = function () {
            num++
            console.log(num)
        }
        return sayFun
    }
    var say = say667()
    say() // 667
    say() // 668

· javascript 代码中的”use strict”;是什么意思 ? 使用它区别是什么?

  'use strict'是ECMAScript5添加的(严格)运行模式。

  使用 'use strict' 消除代码运行的一些不安全之处。函数必须声明在顶层,不会自动提升;eval函数的行为会不同。

· 如何判断一个对象是否属于某个类?

  通过instanceof可以判断一个对象是否属于某个类(某个构造函数)。

    function P () {}
    function F () {
        P.call(this)
    }
    F.prototype = new P()
    F.prototype.constructor = F
    var fun = new F()
    console.log(fun instanceof F) // true
    console.log(fun instanceof P) // true

· new操作符具体干了什么呢?

  1. 创建一个新对象。

  2. 将构造函数中作用域赋值给新对象。(因此this指向了这个新的对象)

  3. 执行构造函数中的代码。(给新对象添加属性)

  4. 返回新对象。

· Javascript中,有一个函数,执行对象查找时,永远不会去查找原型,这个函数是:hasOwnProperty。

· 对JSON的了解?

  JSON是一种轻量级的数据交换格式,是javascript对象表示法。简洁和清晰的层次结构使得JSON成为理想的数据交换语言。

/** JSON的格式 */
{
    "name": "hello",
    "sex": "男",
    "age": 26
}
/** 上面是个JSON实例:最外层用'{}'包裹,属性名一定要用",如果属性值是字符串也必须用",如果是数值可不用。*/

· js延迟加载的方式有哪些?

  1. defer属性(页面load‘所有东西加载完包括资源’后执行)。例:

    /** 脚本会延迟到整个页面都解析完才执行 
        <script src=".text1.js" defer="defer"></script>
        <script src=".text2.js" defer="defer"></script>
    */

  2. async属性(页面load前执行;不让页面等待脚本下载和执行,异步加载页面的其它内容。)。例:

    /**
        <script src=".text1.js" async></script>
        <script src=".text2.js" async></script>
    */

  3. 动态创建DOM方式。例:

    function downloadJSAtOnload () {
        var element = document.createElement('script')
        element.src = 'defer.js'
        document.body.appendChild(element)
    }
    if (window.addEventListener) {
        window.addEventListener('load', downloadJSAtOnload)
    } else if (window.attachEvent) {
        window.attachEvent('onload', downloadJSAtOnload)
    } else {
        window.onload = downloadJSAtOnload
    }

  4. 使用jQuery的getScript()方法。例:

    $.getScript('text1.js', function() { // 回调函数,成功获取文件后执行的函数  
        console.log('脚本加载完成')  
    });

  5. 使用setTimeout延迟方法。

  6. 让JS最后加载:把js外部引入的文件放到页面底部,来让js最后引入,从而加快页面加载速度。

· Ajax 是什么? 如何创建一个Ajax?

  1. Ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。

  2.创建Ajax过程:

      - 创建XMLHttpRequest对象,也就是创建一个异步调用对象。

      - 创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息。

      - 设置相应HTTP请求状态变化的函数。

      - 发送HTTP请求。

      - 获取异步调用返回的数据。

      - 使用JavaScript和DOM实现局部刷新。

    /** 如下实例 */
    function ajaxFun () {
        var xhr
        if (window.XMLHttpRequest) {
            // IE7+、Firefox、Chrome、Opera、Safari 浏览器执行的代码
            xhr = new XMLHttpRequest()
        }
        else {
            // IE5、IE6 浏览器执行代码
            xhr = new ActiveXObject('Microsoft.XMLHTTP')
        }
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                console.log('success')
            }
        }
        xhr.open('Get', url, true)
        xhr.send
    }