美文网首页
《JavaScript高级程序设计》学习笔记

《JavaScript高级程序设计》学习笔记

作者: Code_Rush | 来源:发表于2017-05-09 19:43 被阅读0次

    一个完整的JavaScript实现应由以下三个部分组成:

    • ECMASript (核心)
    • DOM (文档对象模型)
    • BOM (浏览器对象模型)

    ECMAScript中有五种简单数据类型:

    • Underfined
    • Null
    • Boolean
    • Number
    • String

    一种复杂数据类型:

    • Object

    注意!

    console.log(typeof(null)); //object
    

    with语句会降低性能。

    ECMAScript函数命名的参数只提供便利,但不是必须的,不介意传递进去多少个参数,也不在乎传进来参数是什么数据类型。
    未指定返回值的函数返回的是一个特殊的undefined值。
    ECMAScript中所有的参数传递的都是值,不可能通过引用传递参数。
    ECMAScript函数没有签名,因为其参数是由包含零或多个值的数据来表示。因为没有签名,所以没有重载。

    JavaScript解释器在执行环境中加载数据时,会率先读取函数声明,使其在执行任何代码之前可用;至于函数表达式,则必须等到解释器执行到它所在的代码行,才会被真正解释执行。

    alert(sum(10,10));  
    function sum(num1, num2){
       return num1 + num2;     
    }
    

    如果将函数声明改为等价的函数表达式,就会在执行期间导致错误。

    alert(sum(10,10));  
    var sum = function(num1, num2){
       return num1 + num2;     
    }
    

    sort函数嵌套:

    function createComparisonFunction(propertyName) {
       return function(object1, object2){
           var value1 = object1[propertyName];
           var value2 = object2propertyName];
           
           if(value1 < value2) {
               return -1;
               } else if (value1 > value2) {
                return 1;
                } else {
                   return 0;
                }
           };
    }
    
    var data = {{name:"test", age:28},{name:"hello", age:"25"}};
    
    data.sort(createComparsionFunction("name"));
    data.sort(createComparsionFunction("age"));
    

    函数内部有两个特殊的对象: arguments和this,arguments有一个callee的属性,是一个指针指向拥有arguments对象的函数。

    //实现递归
    function factorial(num) {
       if(num<=1){
           return 1;
           } else {
               return num*arguments.callee(num - 1);
           }
    }
    

    this引用的是函数据以执行的环境对象。当在网页的全局作用域中调用函数时,this引用的是windows.

    window.color = "red";
    var o = { color: "blue"};
    function sayColor(){
       alert(this.color);
    }
    sayColor(); //"red"
    
    o.sayColor = sayColor;
    o.sayColor(); //"blue"
    

    ECMAScript中的函数是对象,每个函数都有两个属性:length和prototype.
    length表示函数希望接受的命名参数的个数。
    prototype是保存它们所有实例方法的真正所在,诸如toString()和valueFO()等方法都保存在prototype下。
    每个函数都包含两个非继承来的方法:apply()和call(),两个方法都在特定的作用于中调用函数,实际上等于设置函数体内this对象的值。apply()方法接受两个参数:一个在其中运行函数的作用于,另一个是参数数组。

    function sum(num1, num2){
       return num1 + num2;     
    }
    function callSum1(num1,num2){
       return sum.apply(this, arguments);
    }
    function callSum2(num1,num2){
       return sum.apply(this, [num1,num2]);
    }
    alert(callSum1(10,10));   //20
    alert(callSum2(10,10));   //20
    

    call()方法与apply()作用相同,区别在于接收参数的方式不同。对于call()方法而言,第一个参数是this值,变化的是其与参数都直接传递给函数。

    传递参数并非apply()和call()真正用武之地:它们真正强大的是能扩大函数的作用域。

    window.color = "red";
    var o = {color:"blue"};
    
    function sayColor(){
       alert(this.color);
    }
    sayColor();    //red
    sayColor.call(this); //red
    sayColor.call(window); //red
    sayColor.call(o); //red
    

    bind()方法创建一个函数的实例,其this值会被绑定到传递给bind()函数的值。

    window.color = "red";
    var o = {color:"blue"};
    
    function sayColor(){
       alert(this.color);
    }
    var objectSayColor = sayColor.bind(o) ;
    objectSayColor(); //blue
    

    引用类型与基本包装类型的主要区别就是对象的生存期。使用 new 操作符创建的引用类型的实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型的对象,则只存在于一行代码的执行瞬间,然后立即被销毁。这意味着我们不能在运行时为基本类型值添加属性和方法。来看下面的例子:

    var s1 = "some text";
    s1.color = ""red;
    alert(s1.color);     //undefined
    

    ECMA-262 对内置对象的定义是: “由 ECMAScript 实现提供的、不依赖于宿主环境的对象,这些对象在 ECMAScript 程序执行之前就已经存在了。”意思就是说,开发人员不必显式地实例化内置对象,因为它们已经实例化了。

    Global(全局)对象可以说是 ECMAScript 中最特别的一个对象了,因为不管你从什么角度上看,这个对象都是不存在的。ECMAScript 中的 Global 对象在某种意义上是作为一个终极的“兜底儿对象来定义的。换句话说,不属于任何其他对象的属性和方法,最终都是它的属性和方法。事实上,没有全局变量或全局函数;所有在全局作用域中定义的属性和函数,都是 Global 对象的属性。

    当解析器发现代码中调用 eval()方法时,它会将传入的参数当作实际的 ECMAScript 语句来解析,然后把执行结果插入到原位置。通过 eval()执行的代码被认为是包含该次调用的执行环境的一部分,因此被执行的代码具有与该执行环境相同的作用域链。这意味着通过 eval()执行的代码可以引用在包含环境中定义的变量,举个例子:

    //在环境外定义
    var msg = "hello world!";
    eval('alert(msg)');   //"hello world!"
    
    //在eval环境内定义
    eval("function sayHi() { alert('Hi');}");
    sayHi();
    

    window ECMAScript 虽然没有指出如何直接访问 Global 对象,但 Web 浏览器都是将这个全局对象作为window 对象的一部分加以实现的。因此,在全局作用域中声明的所有变量和函数,就都成为了 window对象的属性。

    操作基本类型值的语句一经执行完毕,就会立即销毁新创建的包装对象。在所有代码执行之前,作用域中就已经存在两个内置对象: Global 和 Math 。在大多数ECMAScript实现中都不能直接访问 Global 对象;不过,Web 浏览器实现了承担该角色的 window 对象。

    面向对象程序设计

    ECMAScript 中有两种属性:

    • 数据属性
    • 访问器属性。
    1. 数据属性
      要修改属性默认的特性,必须使用 ECMAScript 5 的 Object.defineProperty() 方法。这个方法接收三个参数:
    • 属性所在的对象
    • 属性的名字
    • 一个描述符对象
      其中,描述符(descriptor)对象的属性必须是: configurable 、 enumerable 、 writable 和 value 。设置其中的一或多个值,可以修改对应的特性值。
    1. 访问器属性
      访问器属性不包含数据值;它们包含一对儿 getter 和 setter 函数(不过,这两个函数都不是必需的)。在读取访问器属性时,会调用 getter 函数,这个函数负责返回有效的值;在写入访问器属性时,会调用setter 函数并传入新值,这个函数负责决定如何处理数据。

    访问器属性不能直接定义,必须使用Object.defineProperty()来定义:

    vav book = {
        _year: 2004,
        edition: 1
    }
    
    Object.defineProperty(book, "year", {
        get: function(){
            return this._year;
        },
        set: function(newValue){
            if (newValue>2004) {
                this._year = newValue;
                this.edition += newValue - 2004;
            }
        }
    });
    
    book.year = 2005;
    alert(book.edition);  //2
    function(){
      
    }
    

    相关文章

      网友评论

          本文标题:《JavaScript高级程序设计》学习笔记

          本文链接:https://www.haomeiwen.com/subject/rluitxtx.html