zoukankan      html  css  js  c++  java
  • javascript高级程序设计

    一、基本

    1.标识符:

    所谓标识符,就是指变量、函数、属性的名字,或者函数的参数。标识符可以是按照下列格式规则
    组合起来的一或多个字符:
     第一个字符必须是一个字母、下划线(_)或一个美元符号($)
     其他字符可以是字母、下划线、美元符号或数字。
    2.语句:
    ECMAScript 中的语句以一个分号结尾;如果省略分号,则由解析器确定语句的结尾
    虽然语句结尾的分号不是必需的,但我们建议任何时候都不要省略它。因为加上这个分号可以避免很多错误(例如不完整的输入),开发人员也可以放心地通过删除多余的空格来压缩 ECMAScript 代码(代码行结尾处没有分号会导致压缩错误)。另外,加上分号也会在某些情况下增进代码的性能,因为这样解析器就不必再花时间推测应该在哪里插入分号了
    3.变量:
    ECMAScript 的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据。
    4.数据类型:
    typeof:
    鉴于 ECMAScript 是松散类型的,因此需要有一种手段来检测给定变量的数据类型——typeof 就是负责提供这方面信息的操作符。
    Undefined:
    类型只有一个值,即特殊的 undefined。在使用 var 声明变量但未对其加以初始化时,这个变量的值就是 undefined。
    undefined 值是派生自 null 值的,因此 ECMA-262 规定对它们的相等性测试要返回 true:
    alert(null == undefined); //true
    Null:
    类型是第二个只有一个值的数据类型,这个特殊的值是 null。从逻辑角度来看,null 值表示一个空对象指针,而这也正是使用 typeof 操作符检测 null 值时会返回"object"的原因。
    Boolean:
    类型是 ECMAScript 中使用得最多的一种类型,该类型只有两个字面值:true 和 false。
    数据类型======转换为true的值======转换为false的值
    Boolean=======true===============false
    String=======任何非空字符串=========""(空字符串)
    Number======任何非零数字值(包括无穷大)====0和NaN
    Object========任何对象=========null
    Undefined========n/a①=========undefined
    n/a(或 N/A),是 not applicable 的缩写,意思是“不适用”
    Number:
    浮点数:
    var floatNum1 = 1.1;
    var floatNum2 = 0.1;
    var floatNum3 = .1; // 有效,但不推荐
    var floatNum1 = 1.; // 小数点后面没有数字——解析为 1
    var floatNum2 = 10.0; // 整数——解析为 10
    极大或极小的数值:
    可以用 e 表示法(即科学计数法)表示的浮点数值表示,默认情况下,ECMASctipt 会将那些小数点后面带有 6 个零以上的浮点数值转换为以 e 表示法表示的数值(例如,0.0000003 会被转换成 3e-7)。
    访问 Number.NEGATIVE_INFINITY 和 Number.POSITIVE_INFINITY 也可以得到负和正 Infinity 的值。可以想见,这两个属性中分别保存着-Infinity 和Infinity。
    NaN:
    Not a Number在 ECMAScript中,任何数值除以 0会返回 NaN①,因此不会影响其他代码的执行。NaN 本身有两个非同寻常的特点。首先,任何涉及 NaN 的操作(例如 NaN/10)都会返回 NaN,这个特点在多步计算中有可能导致问题。其次,NaN 与任何值都不相等,包括 NaN 本身。
    ECMAScript 定义了 isNaN()函数。这个函数接受一个参数,该参数可以是任何类型,而函数会帮我们确定这个参数是否“不是数值”。isNaN()在接收到一个值之后,会尝试将这个值转换为数值。某些不是数值的值会直接转换为数值,例如字符串"10"或 Boolean 值。而任何不能被转换为数值的值都会导致这个函数返回 true。
    5.操作符
    一元操作符:前置后置的++和--,以及+和-
    位操作符:按内存中表示数值的位来操作数值:
    按位非~:操作数的负值减 1(其二进制值全取反)
    var num1 = 25; // 二进制 00000000000000000000000000011001
    var num2 = ~num1; // 二进制 11111111111111111111111111100110
    alert(num2); // -26
    按位与&:与上相同,对其二进制变化(按位与操作就是将两个数值的每一位对齐,有一个为0则0,都为1则1)
    按位或 | :与上相同,对其二进制变化(按位与操作就是将两个数值的每一位对齐,都为0则0,有一个为1则1)
    按位异或^ :与上相同,对其二进制变化(按位与操作就是将两个数值的每一位对齐,一个1一个0则1,否则0)
    左移<<: 操作符会将数值的所有位向左移动指定的位数(不改变正负号)
    有符号的右移>>: 操作符会将数值的所有位向右移动指定的位数(改变正负号)
    无符号的右移>>>:
    6.语句
    do-while 语句是一种后测试循环语句,即只有在循环体中的代码执行之后,才会测试出口条件。换句话说,在对条件表达式求值之前,循环体内的代码至少会被执行一次。
    while 语句属于前测试循环语句,也就是说,在循环体内的代码被执行之前,就会对出口条件求值。因此,循环体内的代码有可能永远不会被执行。
    label和break continue:
    var num = 0; 
    outermost: 
    for (var i=0; i < 10; i++) { 
     for (var j=0; j < 10; j++) { 
     if (i == 5 && j == 5) { 
     continue outermost; 
     } 
     num++; 
     } 
    } 
    alert(num); //95
    var num = 0; 
    outermost: 
    for (var i=0; i < 10; i++) { 
     for (var j=0; j < 10; j++) { 
     if (i == 5 && j == 5) { 
     break outermost; 
     } 
     num++; 
     } 
    } 
    alert(num); //55
    7.垃圾收集
    JavaScript 具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。
    1:JavaScript 中最常用的垃圾收集方式是标记清除(mark-and-sweep)
    当变量进入环境(例如,在函数中声明一个变量)时,就将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。
    2:另一种不太常见的垃圾收集策略叫做引用计数(reference counting)。引用计数的含义是跟踪记录每个值被引用的次数。
    问题:循环引用。循环引用指的是对象 A 中包含一个指向对象 B 的指针,而对象 B 中也包含一个指向对象 A 的引用
    8.有对函数声明和函数表达式加以区别
          解析器在向执行环境中加载数据时,对函数声明和函数表达式并非一视同仁。解析器会率先读取函数声明,并使其在执行任何代码之前可用(可以访问);至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。
    alert(sum(10,10)); 
    function sum(num1, num2){ 
     return num1 + num2; 
    }
    以上代码完全可以正常运行。因为在代码开始执行之前,解析器就已经通过一个名为函数声明提升
    (function declaration hoisting)的过程,读取并将函数声明添加到执行环境中。对代码求值时,JavaScript
    引擎在第一遍会声明函数并将它们放到源代码树的顶部。所以,即使声明函数的代码在调用它的代码后
    面,JavaScript 引擎也能把函数声明提升到顶部。

    但:把上面的函数声明改为等价的函数表达式,就会在执行期间导致错误。

    alert(sum(10,10)); 
    var sum = function(num1, num2){ 
     return num1 + num2; 
    };
    以上代码之所以会在运行期间产生错误,原因在于函数位于一个初始化语句中,而不是一个函数声
    明。换句话说,在执行到函数所在的语句之前,变量 sum 中不会保存有对函数的引用;而且,由于第一
    行代码就会导致“unexpected identifier”(意外标识符)错误,实际上也不会执行到下一行。
    除了什么时候可以通过变量访问函数这一点区别之外,函数声明与函数表达式的语法其实是等价的。

    9.当作值的函数

    可以从一个函数中返回另一个函数,而且这也是极为有用的一种技术
    function createComparisonFunction(propertyName) { 
     return function(object1, object2){ 
     var value1 = object1[propertyName]; 
     var value2 = object2[propertyName]; 
     if (value1 < value2){ 
     return -1; 
     } else if (value1 > value2){ 
     return 1; 
     } else { 
     return 0; 
     } 
     }; 
    }
    var data = [{name: "Zachary", age: 28}, {name: "Nicholas", age: 29}];
    data.sort(createComparisonFunction("name"));
    alert(data[0].name); //Nicholas
    想要根据某个对象属性对数组进行排序。而传递给数组 sort()方法的比较函数要接收
    两个参数,即要比较的值。可是,我们需要一种方式来指明按照哪个属性来排序。要解决这个问题,
    可以定义一个函数,它接收一个属性名,然后根据这个属性名来创建一个比较函数
    argument.callee
    function factorial(num){ 
     if (num <=1) { 
     return 1; 
     } else { 
     return num * factorial(num-1) 
     } 
    }
    arguments 的主要用途是保存函数参数,
    但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数。
    function factorial(num){ 
     if (num <=1) { 
     return 1; 
     } else { 
     return num * arguments.callee(num-1) 
     } 
    }
    每个函数都包含两个非继承而来的方法:apply()和 call()。这两个方法的用途都是在特定的作
    用域中调用函数,实际上等于设置函数体内 this 对象的值。
    call()方法与 apply()方法的作用相同,它们的区别仅在于接收参数的方式不同。
    call()方法时,传递给函数的参数必须逐个列举出来,apply是参数数组。
    事实上,传递参数并非 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); //blue
    使用 call()(或 apply())来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。
     
    bind:
    ECMAScript 5 还定义了一个方法:bind()。这个方法会创建一个函数的实例,其 this 值会被绑
    定到传给 bind()函数的值。例如:
    window.color = "red"; 
    var o = { color: "blue" }; 
    function sayColor(){ 
     alert(this.color); 
    } 
    var objectSayColor = sayColor.bind(o); 
    objectSayColor(); //blue

    10.前面我们已经介绍了大多数内置对象,例如 Object、Array 和 String。ECMA-262 还定义了两个单体内置对象:Global 和 Math。

    Global 对象的 encodeURI()和 encodeURIComponent()方法可以对 URI(Uniform Resource Identifiers,通用资源标识符)进行编码,以便发送给浏览器。

    一般来说,我们使用 encodeURIComponent() 方法的时候要比使用
    encodeURI()更多,因为在实践中更常见的是对查询字符串参数而不是对基础 URI
    进行编码。
    与 encodeURI()和 encodeURIComponent()方法对应的两个方法分别是 decodeURI()和
    decodeURIComponent()。
    11.最后一个——大概也是整个 ECMAScript 语言中最强大的一个方法:eval()
    eval()方法就像是一个完整的 ECMAScript 解析器,它只接受一个参数,即要执行的 ECMAScript(或 JavaScript)字符串。
  • 相关阅读:
    HDU 5213 分块 容斥
    HDU 2298 三分
    HDU 5144 三分
    HDU 5145 分块 莫队
    HDU 3938 并查集
    HDU 3926 并查集 图同构简单判断 STL
    POJ 2431 优先队列
    HDU 1811 拓扑排序 并查集
    HDU 2685 GCD推导
    HDU 4496 并查集 逆向思维
  • 原文地址:https://www.cnblogs.com/forever-xuehf/p/13508934.html
Copyright © 2011-2022 走看看