zoukankan      html  css  js  c++  java
  • 《JavaScript高级程序设计第三版》——细碎知识痛点整理(第三章到第四章)

    先附上图书在线链接:http://www.chinastor.org/upload/2014-12/14122310427265.pdf

    记录内容:

       近来阅读红皮书,做的些许笔记,因为第一次整理,可能稍显琐碎,望谅解,如发现错误,希望能提出指正,谢谢。2018-05-27

    正文:

    3.1.5 语句

    ECMAScript中的语句以一个分号结尾;

    1 var sum = a + b            // 即使没有分号也是有效的语句——不推荐
    2 var diff = a - b;          // 有效的语句——推荐

    加上;的好处:
    ①加上这个分号可以避免很多错误(例如不完整的输入),②开发人员也可以放心地通过删除多的空格来压缩ECMAScript代码(代码行结尾处没有分号会导致压缩错误)。另外,③加上分号也在某些情况下增进代码的性能,因为这样解析器就不必再花时间推测应该在哪里插入分号了。(利于压缩、避免不完整输入、某些情况下会提供代码性能

    条件控制语句(如if语句)只在执行多条语句的情况下才要求使用代码块,但最佳实践是始终在控制语句中使用代码块——即使代码块中只有一条语句

    var bool = true;
    if(bool){
      console.log("ok");//ok
    }

    3.3 变量
    ECMAScript的变量是松散类型的,所谓松散类型就是可以用来保存任何类型的数据
    typeof是一个操作符而不是函数,因此例子中的圆括号尽管可以使用,但不是必需的

    console.log(typeof null)//object,从逻辑角度来看,null值表示一个空对象指针,而这也正是typeof操作符检测null值会返回object的原因

    使用var声明变量但未对其加以初始化时,这个变量的值就是undefined,未初始化的变量,不能执行真正的操作

    如果定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值。这样一来,只要直接检查null值就可以知道相应的变量是否已经保存了一个对象的引用,如下面的例子所示:

    var car = null;
    if(car != null){
    }
    else{
    alert("变量为空")
    }
    alert(null == undefined); //true

    布尔值转换规则

    Boolean  true  false 
    String  任何非空字符串 ""(空字符串)
    Number 任何非零数字值(包括无穷大) 0和NaN(参见本章后面有关NaN的内容)
    Object  任何对象 null
    Undefined n/a① undefined

    3.4.5 Number类型

    var octalNum1 = 070; // 八进制的56
    var octalNum2 = 079; // 无效的八进制数值——解析为79
    var octalNum3 = 08; // 无效的八进制数值——解析为8
    
    var hexNum1 = 0xA; // 十六进制的10
    var hexNum2 = 0x1f; // 十六进制的31
    
    var floatNum1 = 1.1;    //浮点数值
    var floatNum2 = 0.1; 
    var floatNum3 = .1; // 有效,但不推荐
    
    var floatNum = 3.125e7; // 等于31250000

    浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数。例如,0.1加0.2的结果不是0.3,而是0.30000000000000004 。(ps:涉及到对浮点数运算的,一般都要进行,如Math.round()、Math.floor()、Math.ceil(),分别对应四舍五入,向下以及向上取整

    console.log(Number.MAX_VALUE,Number.MIN_VALUE)
    console.log(isFinite(0.0000000000000321))//判值是否属于最小到最大的范围内

    NaN本身有两个非同寻常的特点。首先,任何涉及NaN的操作(例如NaN/10)都会返回NaN,这个特点在多步计算中有可能导致问题。其次,
    NaN与任何值都不相等,包括NaN本身。例如,下面的代码会返回false:

    alert(NaN == NaN); //false

    4. 数值转换
    有3个函数可以把非数值转换为数值:Number()、parseInt()和parseFloat()。第一个函数,即转型函数Number()可以用于任何数据类型,而另两个函数则专门用于把字符串转换成数值。这3个函数对于同样的输入会有返回不同的结果。
    Number()函数转换注意
    传入的是布尔值,true1 false0

    null值为0 undefined 返回NaN 

    undefined 返回NaN

    字符串,空字符返回0,①011返回11 ②11asdfasdf 返回11 ③hello返回NaN

    parseInt()函数转换注意

    var num2 = parseInt(""); // NaN
    var num1 = parseInt("10", 2); //2 (按二进制解析)
    var num2 = parseInt("10", 8); //8 (按八进制解析)
    var num3 = parseInt("10", 10); //10 (按十进制解析)
    var num4 = parseInt("10", 16); //16 (按十六进制解析)

    parseFloat()只解析十进制值

    var num1 = parseFloat("1234blue"); //1234 (整数)
    var num2 = parseFloat("0xA"); //0 
    var num3 = parseFloat("22.5"); //22.5 
    var num4 = parseFloat("22.34.5"); //22.34 
    var num5 = parseFloat("0908.5"); //908.5 
    var num6 = parseFloat("3.125e7"); //31250000

    转换为字符串

    var age = 11; 
    var ageAsString = age.toString();// 字符串"11" 
    var found = true; 
    var foundAsString = found.toString(); // 字符串"true"

    数值、布尔值、对象和字符串值(没错,每个字符串也都有一个toString()方法,该方法返回字符串的一个副本)都有toString()方法。但null和undefined值没有这个方法。.toString(2)里面参数默认是10,为十进制
    转型函数String(),这个函数能够将任何类型的值转换为字符串

    var value1 = 10;
    console.log(String(value1)); // "10"
    null和undefined没有toString()方法,所以String()函数就返回了这两个值的字面量。

    Object对象
    创建Object类型的实例并为其添加属性和(或)方法,就可以创建自定义对象,如下所示:
    var o = new Object();
    Object类型是所有它的实例的基础。换句话说,Object类型所具有的任何属性和方法也同样存在于更具体的对象中。
    Object的每个实例都具有下列属性和方法。
    ①constructor:保存着用于创建当前对象的函数。对于前面的例子而言,构造函数(constructor)就是Object()。
    ②hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。其中,作为参数的属性名(propertyName)必须以字符串形式指定(例如:o.hasOwnProperty("name"))。
    ③isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型(第5章将讨论原型)。
    ④propertyIsEnumerable(propertyName):用于检查给定的属性是否能够使用for-in语句(本章后面将会讨论)来枚举。与hasOwnProperty()方法一样,作为参数的属性名必须以字符串形式指定。
    ⑤toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。
    ⑥toString():返回对象的字符串表示。
    ⑦valueOf():返回对象的字符串、数值或布尔值表示。通常与toString()方法的返回值相同。

    var test = new Object();
    test.name = "dading";
    console.log(test);//name:dading
    console.log(test.constructor == Object);//true
    console.log(test.hasOwnProperty("name"));//true,属性存在当前对象实例中
    console.log(test.isPrototypeOf("name"));//false,传入的对象不是是传入对象的原型
    console.log(test.propertyIsEnumerable("name"));//true,可循环
    console.log(test.name.toLocaleString());//dading
    console.log(test.name.toString());//dading
    console.log(test.name.valueOf());//dading

    3.5.2 位操作符
    0正1负
    例如,数值18的二进制表示是00000000000000000000000000010010,或者更简洁的10010
    负数,取反加1
    1. 按位非(NOT)

    var num1 = 25; // 二进制00000000000000000000000000011001 
    var num2 = ~num1; // 二进制11111111111111111111111111100110 
    alert(num2); // -26

    2. 按位与(AND)

    var result = 25 & 3; //按位与操作只在两个数值的对应位都是1时才返回1
    alert(result); //1 

    3. 按位或(OR) | 有一个位是1的情况下就返回1
    4. 按位异或(XOR)^ 只有一个1时才返回1
    5. 左移

    var oldValue = 2; // 等于二进制的10 
    var newValue = oldValue << 5; // 等于二进制的1000000,十进制的64

    6.有符号的右移

    var oldValue = 64; // 等于二进制的1000000 
    var newValue = oldValue >> 5; // 等于二进制的10,十进制的2

    7.无符号的右移

    var oldValue = -64; // 等于二进制的11111111111111111111111111000000 
    var newValue = oldValue >>> 5; // 等于十进制的00000111111111111111111111111110(134217726)

    3.5.3 布尔操作符
    1.逻辑非操作符由一个叹号(!)表示

    alert(!NaN); // true

    2. 逻辑与 && 第一个条件错误,后面不执行
    3. 逻辑或 || 第一个条件对的,后面不执行
    3.5.4 乘性操作符
    与没有带数值的值相乘,返回NaN
    3.5.5 加性操作符
    +会拼串
    3.5.6 关系操作符
    如果两个操作数都是字符串,则比较两个字符串对应的字符编码值。

    var result = "Brick" < "alphabet"; //true,比较的是两个字符串中对应位置的每个字符的字符编码值。经过这么一番比较之后,再返回一个布尔值。由于大写字母的字符编码全部小于小写字母的字符编码
    var result = "23" < "3"; //true 当比较字符串"23"是否小于"3"时,结果居然是true。这是因为两个操作数都是字符串,而字符串比较的是字符编码("2"的字符编码是50,而"3"的字符编码是51)
    var result = "a" < 3; // false,因为"a"被转换成了NaN由于字母"a"不能转换成合理的数值,因此就被转换成了NaN。根据规则,任何操作数与NaN进行关系比较,结果都是false。

    3.5.10 逗号操作符

    var num1=1, num2=2, num3=3;

    3.6.5 for-in语句

    var arr = [1,2,3,4,5,6,];
    for(var prop in arr){
    console.log(prop,arr[prop])
    }

    3.6.7 break和continue语句

    var num = Math.floor(Math.random()*5 +1);
    console.log(num)
    switch (num) {
      case 1: 
        console.log("1")
        break;
      case 2: 
        console.log("2")
        break;
      default: console.log("不是1和2");
      }
    }

    4.1.3 传递参数
    在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数,或者用ECMAScript的概念来说,就是arguments对象中的
    一个元素)。在向参数传递引用类型的值时,会把这个值在内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外
    部。

    function addTen(num) { num += 10; return num; }
    var count = 20; 
    var result = addTen(count);
    alert(count); //20,没有变化alert(result); //30 function setName(obj) { obj.name = "Nicholas"; obj = new Object(); obj.name = "Greg"; } var person = new Object(); setName(person); alert(person.name); //"Nicholas"

    在setName()函数中添加了两行代码:一行代码为obj重新定义了一个对象,另一行代码为该对象定义了一个带有不同值的name属性。在把person传递给setName()后,其name属性被设置为"Nicholas"。然后,又将一个新对象赋给变量obj,同时将其name属性设置为"Greg"。如果person是按引用传递的,那么person就会自动被修改为指向其name属性值为"Greg"的新对象。但是,当接下来再访问person.name时,显示的 值仍然是"Nicholas"。这说明即使在函数内部修改了参数的值,但原始的引用仍然保持未变。实际上,当在函数内部重写obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。
    可以把ECMAScript函数的参数想象成局部变量。

    4.2 执行环境及作用域
    某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁(全局执行环境直到应用程序退出——例如关闭网页或浏览器——时才会被销毁)。
    当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境。这样,一直延续到全局执行环境;全局执行环境的变量对象始终都是作用域链中的最后一个对象。

    对于这个例子中的swapColors()而言,其作用域链中包含3个对象:swapColors()的变量对象、changeColor()的变量对象和全局变量对象。swapColors()的局部环境开始时会先在自己的变量对象中搜索变量和函数名,如果搜索不到则再搜索上一级作用域链。changeColor()的作用域链中只包含两个对象:它自己的变量对象和全局变量对象。这也就是说,它不能访问swapColors()的环境。(从内往外找,外不能访问内(环境))

    4.2.2 没有块级作用域

    if(true){
      var color = "blue"; 
      let color1 = "blue";
    }
    console.log(color,color1) //undefined,blue

    2. 查询标识符

    var color = "blue"; 
    function getColor(){ 
      return color; 
    } 
    alert(getColor()); //"blue"

    调用本例中的函数getColor()时会引用变量color。为了确定变量color的值,将开始一个两步的搜索过程。首先,搜索getColor()的变量对象,查找其中是否包含一个名为color的标识符。在没有找到的情况下,搜索继续到下一个变量对象(全局环境的变量对象),然后在那里找到了名为color的标识符。因为搜索到了定义这个变量的变量对象,搜索过程宣告结束。图4-4形象地展示了上述搜索过程。

    访问局部变量要比访问全局变量更快,因为不用向上搜索作用域链

      第4章  变量、作用域和内存问题

    var color = "blue"; 
    function getColor(){ 
      var color = "red"; 
      return color; 
    } 
    alert(getColor()); //"red" 

    getColor()函数中声明了一个名为color的局部变量。调用函数时,该变量就会被声明。而当函数中的第二行代码执行时,意味着必须找到并返回变量color的值。搜索过程首先从局部环境中开始,而且在这里发现了一个名为color的变量,其值为"red"。因为变量已经找到了,所以搜索即行停止,return语句就使用这个局部变量,并为函数会返回"red"。也就是说,任何位于局部变量color的声明之后的代码,如果不使用window.color都无法访问全局color变量。变量查询也不是没有代价的。很明显,访问局部变量要比访问全局变量更快,因为不用向上搜索作用域链。

    4.3 垃圾收集
    找出那些不再继续使用的变量,然后释放其占用的内存。为此,垃圾收集器会按照固定的时间间隔(或代码执行中预定的收集时间),周期 性地执行这一操作。
    4.3.1 标记清除
    垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记(当然,可以使用任何标记方式)。然后,它会去掉环境中的变量以及被 环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量 了。最后,垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

    var element = document.getElementById("some_element");
    var myObject = new Object();
    myObject.element = element; 
    element.someObject = myObject;

    在一个DOM元素(element)与一个原生JavaScript对象(myObject)之间创建了循环引用。其中,变量myObject有一个名为element的属性指 向element对象;而变量element也有一个属性名叫someObject回指myObject。由于存在这个循环引用,即使将例子中的DOM从页面中移除,它 也永远不会被回收。

    myObject.element = null;
    element.someObject = null;

    4.3.4 管理内存
    为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为null来释放其引用——这个做法叫做解除引用 (dereferencing)

    function createPerson(name){ 
      var localPerson = new Object(); 
      localPerson.name = name; 
      return localPerson; 
    } 
    var globalPerson = createPerson("Nicholas"); // 手工解除globalPerson的引用globalPerson = null; 

    在这个例子中,变量globalPerson取得了createPerson()函数返回的值。在createPerson()函数内部,我们创建了一个对象并将其赋给局部 变量localPerson,然后又为该对象添加了一个名为name的属性。最后,当调用这个函数时,localPerson以函数值的形式返回并赋给全局变 量globalPerson。由于localPerson在createPerson()函数执行完毕后就离开了其执行环境,因此无需我们显式地去为它解除引用。但是对于 全局变量globalPerson而言,则需要我们在不使用它的时候手工为它解除引用,这也正是上面例子中最后一行代码的目的。不过,解除一个 值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

    引用类型
    引用类型的值(对象)是引用类型的一个实例。在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起。,以便垃圾收 集器下次运行时将其回收。它也常被称为类,但这种称呼并不妥当。尽管ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的 面向对象语言所支持的类和接口等基本结构。引用类型有时候也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法。

  • 相关阅读:
    Java+7入门经典 -1 简介
    优化算法动画演示Alec Radford's animations for optimization algorithms
    如何写科技论文How to write a technical paper
    开始学习深度学习和循环神经网络Some starting points for deep learning and RNNs
    用500行Julia代码开始深度学习之旅 Beginning deep learning with 500 lines of Julia
    用10张图来看机器学习Machine learning in 10 pictures
    ICLR 2013 International Conference on Learning Representations深度学习论文papers
    ICLR 2014 International Conference on Learning Representations深度学习论文papers
    卷积神经网络CNN(Convolutional Neural Networks)没有原理只有实现
    卷积神经网络Convolutional Neural Networks
  • 原文地址:https://www.cnblogs.com/laomi233/p/9096875.html
Copyright © 2011-2022 走看看