红宝书读书笔记

ECMAScript 与 javaScript 的区别:

https://www.oschina.net/translate/whats-the-difference-between-javascript-and-ecmascript

第三章 基本概念

字面量:给变量赋值时,等号右边都可以认为是字面量。 比如: '8' 字符串字面量 ;8 数字字面量 ;

对于尚未声明过的变量,只能执行一项操作,即使用 typeof 操作符检测其数据类型。

Undefined:变量声明,但是未赋值初始化,此时的值就是undefined。

Null类型表示一个空对象指针。null被认为是一个空对象的引用。

保存浮点数需要的内存空间是整数的两倍,因此ECMAScript会不失时机的将浮点数值转换为整数,如果小数点后面没有跟任何数字,那么这个数值就可以作为整数值来保存。

同样的如果浮点数本身表示的就是一个整数,那么该值也会被转换成一个整数。

对于极大或者极小的数可以用e来表示(科学计数法),一个数值,中间是大写或小写的e,后面是10的幂中的指数。

浮点数值的最高精度是17位小数,但是进行算数计算其精度远远不如整数。

永远不要测试某个特定的浮点数值。(这是基于使用IEEE754数值的浮点计算的通病,ECMAScript并非独此一家,其它使用相同数据格式的语言也存在这个问题。)

Number.MIN_VALUE 5e-324

Number.MAX_VALUE 1.7976931348623157e+308

Infinity 超过最小或最大值,即为负无穷或正无穷。

isFinity() 函数用来测试是否在范围之内,范围内返回true。

NaN,即非数值,用于表示一个本来要返回数值的操作数未返回数值的情况。

任何数值除以非数值都会返回NaN,因此不影响其他代码的执行。

NaN,两个特性,任何涉及NaN操作,都将返回NaN;NaN与任何值不相等,包括NaN本身。

isNaN() 在接受一个值之后,会尝试将这个值转换为数值。某些不是数值的值会直接转换为数值。任何不能被转换为数值的值都会导致这个函数返回true。

有三个函数可以把非数值,转换为数值:

  Number()              //可以用于任何数据类型    null返回0

  parseInt()        //字符串 转数值    只解析数字,第一个字符是不是数字直接返回NaN,遇到非数字直接忽略,只返回数字

  parseFloat()         //字符串 转数值    也是从头开始解析到尾,遇见的第一个点有效,第二个点就是无效了,因此它后面的字符串将被忽略。始终忽略前导0,整数返回整数。

字符字面量,也叫转义序列,用于表示非打印字符。

\n 换行

\t 制表

\b 退格

\r 回车

\f 进纸

\\ 斜杠

\' 单引

\" 双引

\xnn  以十六进制代码nn表示一个字符

\unnn 以十六进制代码nnn表示一个unicode字符

任何字符串的长度都可以通过访问其length属性取得。

字符串特点:ECMAScript中的字符串是不可变的,一旦创建,值即是永久,不可改变。

要改变某个变量保存的字符串,首先要销毁原来的字符串,然后在用另一个包含新值的字符串填充该变量。

例如: var lang = "Java"

                  lang = lang + "Script"

把一个值转换为一个字符串:

l例如:var age = 11;

       ageAsString = age.toString();

toString() 可以输入一个参数,来决定转换输出的进制 , null 和 undefined 值没有toString()方法,所以在不知道包不包含null和undefined时,可以使用转型函数String()

把某个值转换为字符串,可以使用加号操作符,把它与一个字符串("")加在一起。

ECMAScript中的对象就是一组数据和功能的结合。可以通过执行 new 操作符后跟要创建对象类型的名称来创建。

Object是所有对象的基础,所以它的每个实例都具有下列属性和方法:

  constructor:保存着用于创建当前对象的函数。构造函数 (constructor) 就是 Object ()

  hasOwnProperty(proprertyName):用于检查给定的属性在当前对象中是否存在,作为参数的属性名字,必须以字符串的形式,加引号。

  isPrototypeOf(object):用于检查传入的对象时否是当前对象的原型。

  propertyIsEnumerable(propertyName):用于检查传入对象是否是当前对象的原型。

  toLocaleString():返回对象的字符串表示,该字符串与执行环境的地区对应。

       toString():返回对象的字符串表示。

       valueOf():返回对象的字符串、数值或布尔值表示。通常与 toString() 方法的返回值相同。    

布尔操作符:

逻辑非!,逻辑非操作符首先会将它的操作数转换为一个布尔值,然后再对其求反。

同时使用两个逻辑非!!操作符,与对此数值使用Boolean()函数相同,将一个值转换为与其对应的布尔值。

两个和号&&,逻辑与操作属于短路操作,如果第一个操作数为false,即不会对第二个操作数求值。

两个竖线符号||,逻辑或操作,如果第一个操作数为true,同样短路逻辑不会继续操作后面的。

ps:不能在在逻辑与或操作中使用未定义的值。

求模,操作符由一个(%)表示。 //  var result= 26 % 5 ;  // 值为1

字符串加什么都是字符串,()小括号可以提高运算的优先级。    // var ha = " hahahahah " + (6 + 7)

ECMAScript相等由两个等号操作符表示(==) ,不相等(!=),比较之前转换操作数。

全等由三个等于号表示(===),,不全等(!==),比较之前不转换操作数。

==================================完成量1/15======================================

逗号操作符多用于声明多个变量;逗号操作符还可以用来赋值,并总会返回表达式中的最后一项:var num = (5,2,6,0)  // num 的值为 0

do-while 语句是一种后测试循环语句,即只有在循环体中的代码执行之后,才会测试出口条件。换句话说,在对条件表达式求值之前,循环体内的代码至少会被执行一次,因此需要虚幻提中代码至少被执行一次的情形,是十分适合do-while的。

while 语句是前测试循环语句,先判断再执行,循环体内的代码可能永远不会被执行。

for 循环,如果将初始化表达式,控制表达式和循环后表达式全部省略,就会创建一个无限循环。

                for (;;){   // 无限循环

            doSomething();

      }

               而只给出控制表达式实际上就是把 for 循环转换成了 while 循环。

               var count = 10;

       var i = 0;

       for(;i < count;){

           alert(i);

           i++

       }

for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。如果表示要迭代的对象的变量值为 null 或 undefined,for-in 语句会抛出错误。(为了保证兼容性:ES5已更改为不抛出错误,只是不执行循环体)

         for(var propName in window){

               document.write(propName);  

    }

label 语句,定义的标签可以再将来由 break 或 continue 语句引用,一般都要与 for 循环配合使用。场景:循环嵌套。

break语句 会立即退出循环,强制继续执行循环后面的语句。continue 语句,也是立刻退出循环,但是退出后会从循环的顶部继续执行。

switch 语句, 中的每一个情形(case)的含义是:"如果表达式等于这个值(value),则执行后面的语句(statement)"。而 break 关键字会导致代码执行流跳出 switch 语句。如果省略 break 关键字,就会导致执行完当前 case 后,继续执行下一个 case 。最后的 default 关键字则用于在表达式不匹配前面任何一种形式的时候,执行激动代码(因此,也相当于 else 语句)。当有一些故意省略的 break 造成混合时,记得写注释。

        switch (expression){

                case value:statement

                   break;

             case value:statement

                   break;

                case value:statement

                   break;

                default:statement

         }

可以在 switch 语句中使用任何数据类型。其次,每个 case 的值不一定是常量,可以是变量,甚至是表达式。

switch 语句在比较值时使用的是全等操作符,因此不会发生类型转换。          

函数在执行完 return 语句之后停止并立即退出。推荐的做法是要么让函数始终返回一个值,要么永远都不要返回值。严格模式下,函数名和参数名不能是 eval 或 arguments,不能出现同名参数。

ECMAScript 函数不介意参数的个数数据类型,这是因为在ECMAScript中的参数在内部是用一个数组来表示的。函数接受到的始终都是这个数组,而不关心数组中包含哪些参数。实际上在函数体内可以通过 arguments 对象来访问这个参数数组,从而获取传递给函数的每一个参数。

arguments 对象只是与数组类似,因为可以使用方括号语法访问它的每一个属性,使用 length 属性来确定传递进来多少个参数。

arguments 的值永远与对应命名参数的值保持同步,比如 第一个参数 和 arguments[0],内存空间相对独立,但是值保持相同。(严格模式下不允许如此修改)

关于参数,没有传递值的参数将自动被赋予 undefined 值。

没有函数的签名,真正的重载是不可能做到的。

如果在ECMAScript中,将一个函数名定义了两次,则后面的生效,名字只属于后定义的函数。

小结:

①没有为整数和浮点数分别定义不同的数据类型,Number 类型可用于表示所有数值。

②Object 是这门语言所有对象的基础类型。

③严格模式为这门语言中容易出错的地方施加了限制。

④无需指定函数的返回值,因为任何ECMAScript函数都可以在任何时候返回任何值。

⑤实际上,未指定返回值的函数返回的是一个特殊的 undefined 值。

⑥ECMAScript 中也没有函数签名的概念,因为其函数参数是以一个包含零或多个值的数组的形式传递的。

⑦可以向函数传递任意数量的参数,并可以通过 arguments 对象来访问这些参数。

⑧由于不存在函数签名的特性,所以ECMAScript 函数不能重载。 (是能实现类似重载的功能的) 

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

JavaScript 变量松散类型的本质,决定了它只在特定的时间用于保存特定值的一个名字而已。由于不存在定义某个变量必须要保存何种数据类型值的规则,变量的值及其数据类型可以在脚本的生命周期内改变。这可能是一个既有趣又强大,同时又容易出问题的特性。

基本类型指的是简单的数据段,而引用类型指那些可能由多个值构成的对象。

五大基本类型是按值访问的,因为可以操作保存在变量中的实际的值。

引用类型的值是保存在内存中的对象。js不允许直接访问内存中的位置,也就是说不能直接操作对象的内存空间,在操作对象时实际上是操作对象的引用,而不是实际的对象。为此,引用类型的值是按引用访问的。对于引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。

var num1 = 5;

var num2 = num1;

当使用 num1 的值来初始化 num2 时,num2 中也保存了值 5 ,但是 num2 中的 5 与 num1 中的 5 是完全独立的,该值只是 num1 中 5 的一个副本。两个变量任意操作而且不会相互影响。

引用类型与此相反,复制后,原对象与副本是一个指针,指向存储在堆中的同一个对象。因为引用相同的对象,所以互相影响。

传递参数:ECMAScript 中所有函数的参数都是 按值传递的。访问变量有按值按引两种方式。

检查类型:

typeof 操作符是确定一个变量是字符串、数值、布尔值,还是 undefined 的最佳工具。

如果变量的值是一个 对象 或 null ,则 typeof 操作符会返回 "object" 。

虽然在检测基本数据类型时 typeof 是非常得力的助手,但在检测引用类型的值时,这个操作符作用不大。为此ECAMScript提供 instanceof 操作符。

person instanceof Object;   // 变量 person 是Object 么?

colors instanceif Array;       // 变量 colors 是 Array 么?

pattern instanceof RegExp;  // 变量 pattern 是 RegExp么?

如果使用 instanceof 检测基本类型的值时会返回 false,因为基本类型不是对象。

执行环境和作用域:

执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有函数和变量都保存在这个对象中。代码无法访问,但解析器处理数据的时候会在后台使用它。

全局执行环境(ECS)是最外围的一个执行环境,根据ECMAScript实现所在的宿主环境不同,表示执行环境的对象也不一样。在Web浏览器中,全局执行环境被认为是 window 对象,因此所有全局变量和函数都是作为 window 对象的属性和方法创建的。

某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的变量和函数定义也随之销毁(全局执行环境直到应用程序退出-列如关闭网页或浏览器-时才会被销毁)。

每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行后,栈将其环境弹出,把控制权返回给之前的执行环境。

当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。全局执行环境的变量对象始终都是作用域链中的最后一个对象。

局部环境找不到东西,可以到它的父执行环境中去找。

函数的参数也被当做变量来对待,因此其访问规则与执行环境中的其他变量相同。

延长作用域链:  try-catch 语句的 catch 块;   和     with 语句; 这两个语句都会在作用域链的前端添加一个变量对象。对 with 语句来说,会将指定的对象添加到作用域链中。对 catch 语句来说,会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。

提示:with 语句是运行缓慢的代码块,尤其是在已设置了属性值时。大多数情况下,如果可能,最好避免使用它。

for 语句创建的变量 i 即使在 for 循环执行结束后,也依然会存在于外部的执行环境中。
JS中,变量要先声明再初始化。
 
4.3 垃圾清除
(1) 标记清除:js中最常用的垃圾清除方式就是 标记清除(mark-and-sweep)。当变量进入环境中(比如:在环境中声明一个变量)时,就将这个变量标记为 "进入环境" ,而当变量离开环境时,则将其标记为 "离开环境"。
     可以使用任何方式来标记变量。比如,通过翻转某个特殊的位来记录一个变量何时进入环境 或者 使用以一个变量列表,来记录跟踪变量的变化。
     垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后垃圾收集器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。
     2008年为止,主流浏览器基本都是 标记清除式的垃圾收集策略,只不过垃圾收集的时间间隔不同。

(2) 引用计数:即跟踪记录每个值被引用的次数。引用标记+1,包含对这个值引用的变量取得了另外一个值-1,可能会出现循环引用问题,为了避免这类问题,最好在不使用他们的时候手动断开原生 JavaScript 对象与 DOM 元素之间的连接。

myObject.element = null;

element.someObject = null;

将变量设置为 null 意味着切断变量与它此前引用值之间的连接。当垃圾收集器下次运行时,就会删除这些值并回收它们占用的内存空间。 

垃圾收集器的临界值是动态修正,在浏览器中可触发垃圾收集,但是不建议这样做。

     window.CollectGarbage();  // IE 立即执行垃圾收集

     window.opera.collect();       // opera 启动垃圾收集例程

管理内存:

对于具备垃圾收集机制的语言编写程序,开发人员一般不必操心内存管理问题。但是,JavaScript 在进行内存管理及垃圾收集时面临的问题还是有些不同,其中最主要的就是,分配给 Web 浏览器的可用内存数量通常要比分配给桌面应用系统的少。这样做的目的是出于安全的考虑,防止JS网页耗尽全部内存导致系统崩溃。

因此,确保占用最少的内存可以让页面获得更好的性能。优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据。一旦不再有用,最好通过将其值设置为 null 来释放其引用——这个方法叫做解除引用(dereferencing)。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。

小结:

1.JavaScript 变量可以保存两种类型的值:基本类型和引用类型值。基本类型和引用类型有以下特点:

①基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;

②从一个变量向另一个变量复制基本类型的值,会创建这个值的一个副本;

③引用类型的值是对象,保存在堆内存中;

④包含引用类型值的变量实际上包含的并不是对象本身,而是一个指向该对象的指针;

⑤从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量最终都指向同一个对象;

⑥确定一个值是哪种基本类型可以使用 typeof 操作符,确定一个值是哪种引用类型可以使用 instanceof 操作符。

2.所有变量(包括基本类型和引用类型)都存在一个执行环境(也称作用域)当中,这个执行环境决定了变量的生命周期,以及那一部分代码可以访问其中的变量。以下是关于执行环境的几点总结:

①执行环境有全局执行环境(也称为全局环境)和 执行环境 之分;

②每次进入一个新执行环境,都会创建一个用于搜索变量和函数的作用域链;

③函数的局部环境不仅有权访问函数作用域中的变量,而且有权访问其包含(父)环境,乃至全局环境;

④全局环境只能访问在全局环境中定义的变量和函数,而不能直接访问局部环境中的任何数据;

⑤变量的执行环境有助于确定应该何时释放内存。

3.JS是一门具有自动垃圾收集机制的编程语言,开发人员不必关心内存分配和回收问题。JS的垃圾收集例程总结如下:

①离开作用域的值将被自动标记为可以回收,因此将在垃圾收集期间被删除。

②"标记清除" 是目前主流的垃圾收集算法,这种算法的思想是给当前不使用的值加上标记,然后再回收其内存。

③另一种垃圾收集算法是"引用计数",这种算法的思想是跟踪记录所有值被引用的次数。JS引擎目前都不再使用这种算法;但在IE中访问非原生 JavaScript 对象(如DOM元素)时,这种算法仍然可能会导致问题。

④当代码中存在循环引用现象时,"引用计数"算法就会导致问题。

⑤解除变量的引用不仅有助于消除循环引用现象,而且对垃圾收集也有好处。为了确保有效地回收内存,应该及时解除不再使用的全局对象,全局对象属性以及循环引用变量的引用。

第五章 引用类型

引用类型的值是一个引用类型的实例。在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织到一起。尽管ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构。引用类型有时候也被称为对象定义,因为他们描述的是一类对象所具有的属性和方法。

新对象是使用 new 操作符后跟一个构造函数来创建的。构造函数本身就是一个函数,只不过该函数是出于创建新对象的目的而定义的。

var person = new Object();

创建Object引用类型的一个新实例,然后把实例保存在变量 person 中,使用的构造函数是Object,它只为新对象定义了默认的属性和方法。ECMAScript 提供了很多原生引用类型(例如:Object),以便开发人员实现日常的计算任务。

5.1 Object 类型

创建 Object 实例的方式有两种:

第一种是 new 操作符后跟 Object 构造函数

     var person = new Object();

     person.name = "Nicholas";

     person.age = 29; 

第二种是使用对象字面量表示法:       

     var person = {             

        name:"Nicholas",    

        age:29   

     }

     //属性名也可以加引号,这里的属性名是自动转换为字符串。

     //对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象过程

     //通过对象字面量定义对象的时候,实际上不会调用 Object 构造函数。(firefox3之后就不调用了)

在这个例子中,左边的花括号,左边的花括号表示对象字面量的开始,因为它出现在了表达式的上下文(expression context)中。ECMAScript中的表达式上下文指的是该上下文期待的一个值(表达式)。赋值操作符表示后面是一个值,所以左花括号在这里表示一个表达式的开始。同样的花括号,如果出现在一个语句上下文(statement context)中,例如跟在if语句条件的后面,则表示一个语句块的开始。

开发人员更青睐对象字面量语法,因为代码量更少,而且又封装数据的感觉。对象字面量,也是向函数传递大量可选参数的首选方法。

一般来讲命名参数虽然容易处理,但在有多个可选参数的情况下就显得不够灵活。最好的做法是对那些必需值使用命名参数,而使用对象字面量来封装多个可选参数。

一般来说访问对象属性时使用的都是点表示法,这也是很多面向对象语言中通用的语法。不过在js中也可以使用方括号表示法来访问对象的属性。在使用方括号语法时,应该将要访问的属性以字符串的形式放在方括号中。   

例如: person.name;            //"Nicholas"

            person[ " name " ] ;   //"Nicholas"

从功能上看,这两种访问对象属性的方法没有任何区别。但方括号语法的主要优点是可以通过变量来访问属性。

例如:var propertyName = "name";

           alert(person[ propertyName ]);    //"Nicholas"

如果属性名中包含导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括号表示法。

           person[ " first name " ]  = "Nicholas";   

由于 "first name" 中包含一个空格,所以不能使用点表示法来访问它。因为,属性名是可以包含非字母,非数字的,这时候就可以使用方括号表示法来访问。

通常,除非必须使用变量来访问属性,否则我们建议使用点表示法

5.2 Array 类型

ECMAScript 数组与其它语言中的数组都是 数据的有序列表。不同的是,ECMAScript 数组的每一项可以保存任何类型的数据。而且ECMAScript数组大小是可以动态调整的,即可随着数据增加自动增长以容纳新增数据。

创建数组方式有两种:

第一种是使用 Array 构造函数

     var colors = new Array();

     //如果预先知道数组要保存的项目数量,也可以给构造函数传递该数量,该值会自动变成 length 属性的值。

     var colors = new Array(20);    // length值为20的数组

     //也可以直接传入数组包含项    

     //使用 Array 构造函数时也可以省略 new 操作符。

第二种基本方式是使用数组字面量表示法

     //数组字面量由一对包含数组项的方括号表示,多个数组项之间以逗号隔开。

     //与对象一样,在使用数组字面量表示法时,也不会调用 Array 构造函数。

  //因为数组的索引始终是 length-1 ,因此下一个新项的位置就是 length 。即长度值等于最后一项的索引加1。

     // var colors = [ "red","blue","green" ]; 创建一个包含3个字符串的数组

     // colors[colors.length] = "black";                 (在位置3)添加一种颜色

5.2.1 检测数组

自从ECMAScript 3 做出规定之后,就出现了确定某个对象是不是数组的经典问题。

对于一个网页,一个全局作用域而言,instanceof 操作符就可以满足。

但是如果网页包含两个或者多个框架,那就存在多个不同的全局执行环境。从而存在多个不同版本的 Array 构造函数。ECMAScript 5 为此新增 Array.isArray()。这个方法的目的最终是确定某个值到底是不是数组,而不管它是在哪个全局执行环境中创建的。

栈方法:数组可以表现的像栈一样,后者可以限制插入和数据结构。栈是一种LIFO(last in first out)的数据结构。最新添加的项最早被移除。ECMAScript 提供 push()和 pop()方法。push();00栈顶推入,pop();栈顶移除。在调用 pop 时,它会返回数组的最后一项。

队列方法:栈数据结构的访问规则是 LIFO(Last in First Out,后进先出),而队列数据结构的访问规则是 FIFO(Fist-In-Fist-out,先进先出)。队列从列表前端,末端添加。shift();移除数组的第一个项,并返回该项。unshift();在数组前端添加任意项,并返回新数组长度。

reverse();反转数组顺序。

sort();该方法会调用每个数组的 toString()转型方法,其比较的也是字符串。默认情况下,sort()方法按升序排列数组项。

concat();该方法会先创建一个当前数组的副本然后将接收的参数放在副本的末尾,最后返回新构建的数组。无参数,只是复制副本并返回副本。如果传递的参数是一个或多个数组,则将每一项添加到结果数组中。不影响原来的数组。

slice();基于当前数组的一个或者多个项创建一个新数组,可接受两个参数,起始 和 结束 的位置 ,一个 参数就是 起始 至 最后。参数为负,直接用数组长度加上参数确定相应位置。

splice();数组最强大方法。主要用途是向数组中部插入项。

                     有3种用法:

                      删除:可以删除任意数量的项,只需要指定两个参数。即要删除 第一项的位置,要删除的项数。

                      插入:可以向指定位置插入任意数量的项,只需指定三个参数。起始位置,0 (要删除的项数),要插入的项。 

                      替换:可以向指定位置插入任意数量的项,且同时删除任意数量的项,只需指定三个参数。起始位置,要删除的项数,要插入任意数量的项。 

                      // splice()方法始终会返回一个数组,包含的是从原数组删除的项。

                      // var colors = ["red","blue","green"];

                      // var removed = colors.splice( 1,1,"yellow" );  删除一项,插入一项

                      // alert (colors);        // red,yellow,green

                      // alert (removed);    // blue

ES5为数组实例添加了两个位置方法:indexOf()和 lastIndexOf()。都接收两个参数:要查找的项 和 (可选)表示查找起点位置的索引。indexOf()从前往后查找,lastIndexOf()从后往前查找。这俩个方法都返回要查找的项在数组中的位置,没找到返回 -1 。要查找的项必须严格相等,第一个参数与数组每一个项作比较时,使用的就是全等操作。

==================================完成量2/15======================================

猜你喜欢

转载自www.cnblogs.com/goforxiaobo/p/12691538.html