从零开端学习前端JAVASCLANDIPT — 壹、JavaScript基础

2019-05-04 13:29栏目:ca888圈内

实际上,Number背后的真正规则复杂得多,内部处理步骤如下:
1:调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。
2:如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。
3:如果toString方法返回的是对象,就报错。

五、js注释

注释可用于提高代码的可读性。Javascript不会执行注释,用户也不会看到注释,注释只是方便开发者更好的理解JS代码。

单行注释:以//开头。

// 这是一行单行注释 

多行注释:以/*开头,以*/结尾。 

/* 第一行注释 第二行注释 */

文档注释:以/**开头,以*/结尾。 

/** 这是文档的注释 */

重要注释:以/*!开头,以*/结尾 

/*! 这是非常重要的注释 */ 

 

1 {valueOf:function(){return2;}}// 3

/*
 * 强制类型转换
 *     - 指将一个数据类型强制转换为其他的数据类型
 *     - 类型转换主要指,将其他的数据类型,转换为String 、Number 、Boolean
 *         
 */

/*
 * 将其他的数据类型转换为String
 *  方式一:
 *         - 调用被转换数据类型的toString()方法
 *         - 该方法不会影响到原变量,它会将转换的结果返回
 *         - 但是注意:null和undefined这两个值没有toString()方法,如果调用他们的方法,会报错
 * 
 *  方式二:
 *         - 调用String()函数,并将被转换的数据作为参数传递给函数
 *         - 使用String()函数做强制类型转换时,
 *             对于Number和Boolean实际上就是调用的toString()方法
 *             但是对于null和undefined,就不会调用toString()方法
 *                 它会将 null 直接转换为 "null"
 *                 将 undefined 直接转换为 "undefined"
 * 
 */

//1.调用被转换数据类型的toString()方法
var a = 123;
a = a.toString();
console.log(typeof a); //string

a = true;
a = a.toString();
console.log(typeof a); //string

a = null;
a = a.toString(); 
console.log(typeof a); //报错,Uncaught TypeError: Cannot read property 'toString' of null

a = undefined;
a = a.toString(); 
console.log(typeof a); //报错,Uncaught TypeError: Cannot read property 'toString' of undefined

//---------------------------------------------------------------------------------------------

//2.调用String()函数,并将被转换的数据作为参数传递给函数
a = 123;
a = String(a);
console.log(typeof a); //string

a = null;
a = String(a);
console.log(typeof a); //string

a = undefined;
a = String(a);
console.log(typeof a); //string

//3.我用Java中的方法,发现也是可以的
var b = 123;
b = ""   b;
console.log(typeof b); //string

六、js变量

变量是存储信息的容器,用var关键词来声明(创建)变量。

1)变量定义(声明):

先定义后赋值:

var age;    //var 是关键字,age是变量名

age = 20;  //20是数据 “=”是赋值

定义的同时赋值: var age=20;

一条语句中声明多个变量,该语句以var开头,并使用英文逗号分隔。

  var x= '加数', y= '加数',z='和';

2)变量的分类

全局变量:在所有的函数外部定义的变量和函数内部不使用var关键字则为全局变量 

局部变量:在函数内部定义的变量且必须以var开头申明

<script type="text/javascript"> 
    // 全局变量 
    name = 'xiaoming';
     function func(){ 
            // 局部变量 
            var age = 18; 
            // 全局变量 
            sex = "man" 
    } 
</script>                    

  

var a = 5;
var b = 6;
var c = 12;
//在此之前定义的三个变量都是全局变量(页面关闭后被删除)
function sum() {
    var c = a   b;//局部变量(生存周期:函数执行完毕后被删除)
    console.log(c);//在此输出的是局部变量,则输出结果:11
}
sum();
console.log(c); //在此输出的变量是全局变量,则输出的结果:12

  

var a = 5;//全局变量
(function () {
 var a = 7;//局部变量,作用域为此函数代码块内
 sum();
})();

function sum() {
 console.log(a   4);//a的值是全局变量的值,故输出的结果为9
}

   

注:1, 变量也可以不定义,但强烈不推荐。 2, 变量必须先赋值再使用

附录:

Boolean([])//

trueBoolean({})// true

2>String强制转换参数为原始类型值的转换规则:
数值:转为相应的字符串。
字符串:转换后还是原来的值。
布尔值:true转为"true",false转为"false"。
undefined:转为"undefined"。
null:转为"null"。

十、运算符的优先级(自上而下递减 ,水平同级) 

1》.(对象、类的属性或字段访问)     [](数组下表)       ()(函数调用)    :(三目表达式的分组—表达式的分组)

2》 、--、!、delete(删除对象的某个属性及属性值)、new(创建构造函数和创建对象)、typeof

3》*、/、%

4》 、-、   加、减、字符串连接

5》关系运算符、instanceof(判断某个对象是否是某个类的一个实例)

6》逻辑运算符

7》赋值运算符

()作用:可以表达式分组、改变运算符的优先级、函数调用。

例:a=!6<7  =>   true

推理:a=(!6)<7    =>     a=false<7     =>    a=0<7    =>        true               

14:JavaScript语句

(一)选择语句

1)if语句

(1)单一选择结构:if(){}  (2)二路选择结构:if(){}else{}  (3)三目运算符:?:  (4)多路选择结构:if(){}else if(){}else if(){}else{}

多路选择结构流程图:

图片 1

2)switch语句

语法:switch(condition){case :break;default:}

break具体讲解:阻止代码向下一个case运行。防止case穿透。

default具体讲解:匹配不存在时做的事情。

switch:严格检查类型,如果不统一,条件不成立

(二)循环语句

1)for循环语句

2)for in语句

3)while循环语句

4)do-while语句

var num = 0;
do {
  num  ;
}while (num>10);

 

  

 

(三)Label语句

 

//label语句   跳出双重循环   例:条件 i=5 j=5 时  跳出嵌套的双重for循环   num=55;
var num = 0;
outPoint:
for (var i=0;i<10;i  ) {
      for (var j=0;j<10;j  ) {
            if (i==5 && j==5) {
                break outPoint;
            }
            num  ;
      }
}
console.log(num); //控制台输出

 

(四)异常处理

 

String函数:强制转换成字符串

强制转换主要指使用Number、String和Boolean三个构造函数,手动将各种类型的值,转换成数字、字符串或者布尔值。

九、运算符

  • 算术运算符: 、-、*、/、%(取余)、 (递增)、--(递减)

   运算符:可用于把字符串变量连接起来。

  var  a=1 "5"  //结果为15(字符串)

  //当用/运算符的时候,Math.round的用法(四舍五入)。

 var a = 9 ,b = 7; 
// Math.round:四舍五入到整数位 表达式Math.round(9/7)=1,如果想四舍五入到某小数位则先乘后除 
var c = Math.round(9 / 7 * 100) / 100; 
document.write(c);

parseInt:将字符串转换成整数,从字符串左侧依次查找数值,直到碰到非数值的字符结束

parseFloat:将字符串转换成浮点数(带有小数点的数值)。

NaN:not a number  (NaN类型是Number,可用typeof来查看相关类型)

  var a = '0.128.6.7px';

  var b = parseInt(a);   //b=0

  var b = parseFloat(a);  //b=0.128

  document.write(b); 

  

var a = 10.4, b = 7;
//var c = a% b ;
/*按照正常算法3.4,但是js定义的变量都是弱类型,精度相对来说较低出来的结果大概是
3.400000000000000000004,结果接近我们处理的方式如下:*/ 
var c = a * 10 % b / 10;
document.write(c);

    

//    (自增) => 前自增(  a)、后自增(a  )
var a = 5; 
// a的前自增:变量本身先自增1,然后再将结果赋予当前位置 
// a的后自增:变量的值先赋予当前位置,然后变量本身再自增1 
var b = 4   a  ; 
document.write(a); // 6 
document.write(b); // 9

  --a和a--原理同 a和a

 var a = 4, b = 3;
 var c = (a       b   b--   --a) % 5;
 //表达式对应值:4 4 4 4 
 /*对应位置a、b的值:
 先4参与运算后加a=5、
 先加  b在运算b=4、 
 先4参与后减b=3、
 先减--4后运算a=4 */
 document.write(a); //4
 document.write(b); //3
 document.write(c); //1

 

  赋值运算符:=、 =、-=、*=、/=、%=

var a = 4, b = 5;
a  = b; // a = a   b; 
a %= b; // a = a % b; 
document.write(a); 
document.write(b);
  • 关系(比较)运算符:>、<、>=、<=、==、===、!=、!==

===与==的区别:

对于string和number等基本类型,不同类型之间比较:

1、==比较会将变量隐式转换成同一类型的值进行比较。

2、===如果类型不同,其结果就是不等。

如果是array和object等引用类型,==和===没有区别.如果两个的变量是同一个对象就为true,否则为false。

基本类型和引用类型进行比较,==会将引用类型转换成基本类型,再进行值比较。而===因为类型不同,结果为false。

// == 和 === 
// 基本数据类型 
var a = 5, b = '5'; 
document.write(a == b); //true 
document.write(a === b);//fasle 

// 引用数据类型:看两侧的变量是否为同一个对象,是则true,不是则false 
var a = {}, b = {}; 
document.write(a == b); //false a、b不同的对象直接返回false
document.write(a === b); //false a、b不同的对象直接返回false
  • 逻辑运算符:&&、||、!

图片 2

  •  三目运算符(简化代码):? :

    // 三目运算符:condition ? if_true : if_false;

    var c = 5 > 4 ? '恩' : '哦'; alert(c); //c=恩

13:程序的三大结构

1.顺序结构

图片 3

 

2.选择结构

 图片 4

3.循环结构

 图片 5

以下六个值的转化结果为false,其他的值全部为true。

Number(324) 值:324 字符串如果可以被解析为数值,则转换为相应的数值
Number('324abc')  值:NaN 字符串:如果不可以被解析为数值,返回NaN
Number('')  值:0 空字符串转为0
Number(true) 、Number(false) 值:1、0 布尔值:true 转成1,false 转成0
Number(undefined) 值:NaN undefined:转成 NaN
Number(null) 值:0 null:转成0

附录:

进制间的转换(二进制、八进制、十进制、十六进制)

1>10进制转换为16进制:(10).tostring(16)

2>8转16:(012).tostring(16)

3>16转10:(0x).tostring(10)

4>10转2:(111111).tostring(2)

5>16转8:(0x16).tostring(8)

6>parseInt(10,2)

7>parseInt(12,16)

8>parseInt(12,8)

 

 

图片 6


如果toString方法返回的是复合类型的值,再调用valueOf方法,如果valueOf方法返回的是原始类型的值,则对该值使用String方法,不再进行以下步骤。

参数为原始类型值的转换规则:

三、JS组成 

图片 7

11:强制转换

强制转换主要指使用Number、String和Boolean三个构造函数,手动将各种类型的值,转换成数字、字符串或者布尔值。

1:Number强制转换

参数为原始类型值的转换规则:

原始类型的值主要是字符串、布尔值、undefined和null,它们都能被Number转成数值或NaN。

NaN:not a number,当数学计算得不到数字结果时,该值就是NaN。

isNaN:判断变量是否为NaN。

// 数值:转换后还是原来的值

Number(324) // 324

// 字符串:如果可以被解析为数值,则转换为相应的数值

Number('324') // 324

// 字符串:如果不可以被解析为数值,返回NaN

Number('324abc') // NaN

// 空字符串转为0

Number('') // 0

// 布尔值:true 转成1,false 转成0

Number(true) // 1

Number(false) // 0

// undefined:转成 NaN

Number(undefined) // NaN

// null:转成0

Number(null) //0

Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN。

参数为对象的转换规则:

简单的规则是,Number方法的参数是对象时,将返回NaN。

Number({a: 1}) // NaN

Number([1, 2, 3]) // NaN

实际上,Number背后的真正规则复杂得多,内部处理步骤如下:

1:调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。

2:如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。

3:如果toString方法返回的是对象,就报错。

2:String强制转换

参数为原始类型值的转换规则:

数值:转为相应的字符串。

字符串:转换后还是原来的值。

布尔值:true转为"true",false转为"false"。

undefined:转为"undefined"。

null:转为"null"。

参数为对象的转换规则:

String方法的参数如果是对象,返回一个类型字符串;如果是数组,返回该数组的字符串形式。

String内部处理步骤如下:

1:先调用对象自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。

2:如果toString方法返回的是对象,再调用valueOf方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。

3:如果valueOf方法返回的是对象,就报错。

3:Boolean强制转换

参数为原始类型值的转换规则:

转换规则相对简单:除了以下六个值的转换结果为false,其他的值全部为true。

undefined、null、-0、0或 0、NaN、''(空字符串)

参数为对象的转换规则:

所有对象(包括空对象)的转换结果都是true。


 

0

二十、数组 

定义:数组是一个可以存储一组或一系列相关数据的容器。

为什么要使用数组?

   1:为了解决大量相关数据的存储和使用的问题。

   2:模拟真实的世界(班级、军队)。

1>数组的操作

1)创建数组

  (1)构造函数的方式:var a=new Array();

  (2)隐式声明的方式:var b=[];

2)数组的赋值

构造函数函数的方式

(1)直接赋值:var a=new Array(数据1,数据2,…);

    注:var a=new Array(数值)       如果括号中只有一个元素,并且这个元素是数值类型的,那么他就是指定数组的长度。 并且它的值都是undefined。

  数组的属性:length 属性(获取整个数组的长度)。

(2)先声明后赋值:var a=new  Array(); a[0]=1;  a[1]=2;  a[2]=3;

隐式声明赋值

(1)直接赋值: var a=[1,2,3,4];

(2)声明以后再赋值: var a=[]; a[0]=1;  a[1]=2;  a[2]=3;

注:JS数组可以存储任何类型的值。eg: arr[3] = function () {}; 

3)访问数组 

  通过数组的(中括号)下标访问。 

    arr[0-(length-1)] //数组下标从0开始,他的最大值,是length-1。

  arr['name'] //关联数组 通过下表字符串进行访问

4) 修改数据: 

arr[3] = '修改的数据';

5)删除数据:

delete arr[1]; 

6)遍历数组

1:for循环。

for(var i = 0; i < arr.length; i  ) {
  console.log(arr[i]);
}

2:while循环。

var i = 0;
while(i < arr.length) {
  console.log(arr[i]);
  i  ;
}

3:for in循环。(遍历数组不常用)

  数组的遍历。

for(var attr in arr){
  //attr 数组的下标
  console.log(arr[attr])
}

对象属性的遍历。

// 使用for in 遍历对象
var obj = {name: '小明', age: 24, hobby: ['打篮球', '搏击', '打乒乓球']};
for(var attr in obj) {
  console.log(obj[attr]);
}

2>数组分类

1:按照下标的类型

     1.下标是数字的类型叫做(索引数组)

var arr = ['1', '2' , '3'];

 2.下标是字符串类型叫做(关联数组),必须通过对象模拟的形式才能实现,一般不用。

var arr = [];
arr['name'] = '张三';
arr['age'] = '28';

3:按照维度来分类

  1.一维数组常用的数组就是一维数组

  2.二维数组,通过对象模拟的形式才能实现。

  声明二维数组:

 var arr=[[1,2,3],[4,5,6]];    alert(arr[1][1]); //值5

3>数组的属性 

(1)length: 设置或返回数组元素的数目。(可读可写)

length属性控制数组的读:console.log(arr.length-1);

length属性控制数组的写:arr.length = 6; 

(2)constructor:返回构造函数的引用。(输出constructor的返回值:Array)

4>数组的方法(加粗常用)

  前五个对原始对象的操作

1. arr.push(数组元素1,数组元素2,........)   向数组的末尾加入新元素 | 返回值:新数组的长度

 eg:arr.push('追加元素1','追加元素2');

2.arr.unshift(数组元素1,数组元素2,........)  向数组的开头加入新元素 | 返回值是新数组的长度。

 eg:arr.unshift(开头新元素1,开头新元素2)

3. arr.pop()    删除数组的最后一个元素 | 返回值是删除的元素。 

var first = arr.pop();

4. arr.shift()  删除数组的第一个元素 | 返回删除的元素。

var first = arr.shift();

5.万能的添加删除函数 arr.splice(index,数量,添加的元素.....)  注:前俩个元素必须有 

   (1)index   从何处开始添加或删除,必须是数值类型(数组的下标) 

   (2)数量    规定了删除的个数,如果是0,则不删除。 

   (3)需要添加的元素,可以当作替换的元素。 

   (4)如果有删除的元素,以数组的方式返回删除的元素。 

// 添加元素
arr.splice(2, 0, '王五');
// 修改元素
arr.splice(1, 1, '王五');
//修改与添加
arr.splice(1, 1, '王五','李四');
// 删除元素
var del = arr.splice(1, 1);

 6.arr.join([分隔符])   把数组元素按照指定分隔符组合成一个字符串,如果没有指定分隔符,默认是用“,”分割 | 返回结果就是组合成的字符串。

var param = {
    q: '棉衣',
    commend: 'all',
    search_type: 'item'
};

var aParam = [];
for(var attr in param) {
    aParam.push(attr   '='   param[attr]);
}
console.log(aParam.join('&'));  //以字符&分割连接数组
//结果:q=棉衣&commend=all&search_type=item

7.  arr.slice() 数组的分割。从截取指定的开始位置,到结束位置(不包括)的元素。如果不指定结束位置,则从指定的开始位置,取到结尾(数组的下标)。 

支持负数(-1开头)  返回的是新数组。 不改动原来的数组。正数和负数都是向右查找 

var arr = ['宋江', '卢俊义', '武松', '杨雄', '石秀', '鲁智深'];
var newArr = arr.slice();相当于拷贝数组
var newArr = arr.slice(2);//不指定结束为止,默认为截取到最后
var newArr = arr.slice(2, 5);//结果为下标为2、3、4的数组元素,不包含为指定结尾下标数的元素
var newArr = arr.slice(-2, -1);  //从末尾开始计数分割  只能按照从左向右的顺序进行截取,即不支持arr.slice(-1, -2)   结果:'石秀'

8. arr.concat()   连接两个或更多的数组,并返回新数组,对原数组没有任何影响。 

eg:arr1.concat(arr2)  //将数组arr1和arr2连接成新数组返回

9.arr.reverse()  数组翻转方法。改变原数组 

arr.reverse(arr)  //将数组翻转

10.  arr.sort()   对数组进行排序,如果没有参数,则按照字母的编码进行排序,如果要按照其他的顺序来排序,要提供一个函数。

回调函数会提供两个参数(a,b)。

a<b  a在b前。

a=b  顺序按照原样输出。

a>b  b在a前。 

['d', 'c', 'b', 'a'].sort()  // ['a', 'b', 'c', 'd'] 
[4, 3, 2, 1].sort()  // [1, 2, 3, 4] 
[11, 101].sort()  // [101, 11] 
[10111, 1101, 111].sort()  // [10111, 1101, 111] 

如果想让sort方法按照自定义方式排序,可以传入一个函数作为参数,表示按照自定义方法进行排序。该函数本身接受两个参数,表示进行比较的两个元素。如果返回值大于0,表示第一个元素排在第二个元素后面;其他情况下,都是第一个元素排在第二个元素前面。

返回值正直交换   零、负值不交换  负值降序   正值升序

 [10111, 1101, 111].sort(function (a, b) { 
     return a - b; //回调函数
})   //输出结果: [111, 1101, 10111] 
[ { name: "张三", age: 30 }, { name: "李四", age: 24 }, { name: "王五", age: 28 } ].sort(function (o1, o2) { 
    return o1.age - o2.age;
})   // [ { name: "李四", age: 24 }, { name: "王五", age: 28 }, { name: "张三", age: 30 } ] 

二十一、排序

1>冒泡排序 

图片 8图片 9

// 冒泡排序:从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒
var arr = [23, 34, 11, 22, 19, 18];

/*
    冒泡排序的思路分析:
    第1轮 第1步:[23, 34, 11, 22, 19, 18]
    第1轮 第2步:[23, 11, 34, 22, 19, 18]
    第1轮 第3步:[23, 11, 22, 34, 19, 18]
    第1轮 第4步:[23, 11, 22, 19, 34, 18]
    第1轮 第5步:[23, 11, 22, 19, 18, 34]

    第2轮 第1步:[11, 23, 22, 19, 18, 34]
    第2轮 第2步:[11, 22, 23, 19, 18, 34]
    第2轮 第3步:[11, 22, 19, 23, 18, 34]
    第2轮 第4步:[11, 22, 19, 18, 23, 34]

    第3轮 第1步:[11, 22, 19, 18, 23, 34]
    第3轮 第2步:[11, 19, 22, 18, 23, 34]
    第3轮 第3步:[11, 19, 18, 22, 23, 34]

    第4轮 第1步:[11, 19, 18, 22, 23, 34]
    第4轮 第2步:[11, 18, 19, 22, 23, 34]

    第5轮 第1步:[11, 18, 19, 22, 23, 34]
*/

冒泡排序的思路推演

  

for(var i = 1; i < arr.length; i  ) {
 // 内层for循环确定每轮的步数
 for(var j = 0; j < arr.length - i; j  ) {
  // 两两比较
  if(arr[j] > arr[j   1]) {
   var temp = arr[j];
   arr[j] = arr[j   1];
   arr[j   1] = temp;
  }
 }
}

2>选择排序 

图片 10图片 11

//选择排序:两两比较,找到最大值(或者最小值)之后,将其放在正确的位置,其他数的位置不变。
/*
    选择排序的思路分析:
    第1轮 第1步:var iMinK = 0;
    第1轮 第2步:23 和 34比较,什么也不做
    第1轮 第3步:23 和 11比较,iMinK = 2
    第1轮 第4步:11 和 22比较,什么也不做
    第1轮 第5步:11 和 19比较,什么也不做
    第1轮 第6步:11 和 18比较,什么也不做
    第1轮 第7步:下标0和下标2进行位置交换 [11, 34, 23, 22, 19, 18]

    第2轮 第1步:var iMinK = 1;
    第2轮 第2步:34 和 23比较,iMinK = 2
    第2轮 第3步:23 和 22比较,iMinK = 3
    第2轮 第4步:22 和 19比较,iMinK = 4
    第2轮 第5步:19 和 18比较,iMinK = 5
    第2轮 第6步:下标1和下标5进行位置交换 [11, 18, 23, 22, 19, 34]
*/

选择排序的思路推演

 

// 外层for循环确定轮数
for(var i = 0; i < arr.length - 1; i  ) {
 // 记录最小值的下标
 var iMinK = i;
 for(var j = i   1; j < arr.length; j  ) {
  if(arr[iMinK] > arr[j]) {
   iMinK = j;
  }
 }
 // 交换数据
 if(iMinK !== i) {
  var temp = arr[i];
  arr[i] = arr[iMinK];
  arr[iMinK] = temp;
 }
}

  3>插入排序

图片 12图片 13

在要排序的一组数中,假设前面的数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。


/*
插入排序的思路分析:
第1轮 第1步:[23, 34, 11, 22, 19, 18]


第2轮 第1步:[23, 11, 34, 22, 19, 18]
第2轮 第2步:[11, 23, 34, 22, 19, 18]


第3轮 第1步:[11, 23, 22, 34, 19, 18]
第3轮 第2步:[11, 22, 23, 34, 19, 18]
第3轮 第3步:[11, 22, 23, 34, 19, 18]


第4轮 第1步:[11, 22, 23, 19, 34, 18]
第4轮 第2步:[11, 22, 19, 23, 34, 18]
第4轮 第3步:[11, 19, 22, 23, 34, 18]
第4轮 第4步:[11, 19, 22, 23, 34, 18]


第5轮 第1步:[11, 19, 22, 23, 18, 34]
第5轮 第2步:[11, 19, 22, 18, 23, 34]
第5轮 第3步:[11, 19, 18, 22, 23, 34]
第5轮 第4步:[11, 18, 19, 22, 23, 34]
第5轮 第5步:[11, 18, 19, 22, 23, 34]
*/

插入排序的思路分析

 

for(var i = 1; i < arr.length; i  ) {
 // 内层的for循环
 for(var j = i; j > 0; j--) {
  if(arr[j] < arr[j - 1]) {
   var temp = arr[j];
   arr[j] = arr[j - 1];
   arr[j - 1] = temp;
  } else {
   break;
  }
 }
}

   4>快速排序

图片 14图片 15

//选择一个基准元素,通常选择第一个元素或者最后一个元素。
//通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素。
//此时基准元素在其排好序后的正确位置,然后在用同样的方法递归的排序划分的两部分。


/*
排序数组:23, 35, 34, 11, 22, 19, 18
快速排序的思路分析:
第一步:base = 23 , arr = [35, 34, 11, 22, 19, 18]
第二步:left = [], right = []
第三步:[11, 22, 19, 18] 23 [35, 34]
第四步: [] 11 [22, 19, 18] 23 [34] 35 []
第五步:[] 11 [19, 18] 22 [] 23 [34] 35 []
第六步:[11, 18, 19, 22, 23, 34, 35]
*/


/*
if(arr.length <= 1) {
return arr; 
}
var iBase = arr.shift();
var left = [], right = [];


for(var i = 0; i < arr.length; i  ) {
if(arr[i] < iBase) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
left: [11, 22, 19, 18] iBase: 23 , right: [35, 34]

从上开始正推返回表达式:return quickSort(left即[11,22,19, 18]).concat(iBase=23, quickSort(right即[35,34]));


从下开始逆推返回值:return [11, 18, 19, 22].concat(23, [35,34]);//合并后的数组:[11,18,19,22,23,34,35]


-------------------------------------------我是单次递归分割线-----------------------------------------------


if(arr.length <= 1) {
return arr; 
}
var iBase = arr.shift();
var left = [], right = [];


for(var i = 0; i < arr.length; i  ) {
if(arr[i] < iBase) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}


left: [] iBase: 11 right: [22, 19, 18]

从上开始正推返回表达式:return quickSort(left即[]).concat(iBase=11, quickSort(right即[22,19,18]));


从下开始逆推返回值:return [].concat(11, [18, 19, 22]); //合并后的数组:[11, 18, 19, 22]


-------------------------------------------我是单次递归分割线-----------------------------------------------


if(arr.length <= 1) {
return arr; 
}
var iBase = arr.shift();
var left = [], right = [];


for(var i = 0; i < arr.length; i  ) {
if(arr[i] < iBase) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}


left: [19, 18] iBase: 22 right: []

从上开始正推返回表达式:return quickSort(left即[19, 18]).concat(iBase=22, quickSort(right即[]));


从下开始逆推返回值:return [18, 19].concat(22, []); //合并后的数组: [18, 19, 22]


-------------------------------------------我是单次递归分割线-----------------------------------------------


if(arr.length <= 1) {
return arr; 
}
var iBase = arr.shift();
var left = [], right = [];
for(var i = 0; i < arr.length; i  ) {
if(arr[i] < iBase) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
left: [18] iBase: 19, right: []
从上开始正推返回表达式:return quickSort(left即[18]).concat(iBase=19, quickSort(right即[]));
从下开始逆推返回值:return [18].concat(19, []); //合并后的数组: [18, 19]

*/

快速排序思路推演

  

var arr = [23, 35, 34, 11, 22, 19, 18, 18];
function quickSort(arr) {
 if(arr.length <= 1) {
  return arr; 
 }
 var iBase = arr.shift();
 var left = [], right = [];

 for(var i = 0; i < arr.length; i  ) {
  if(arr[i] < iBase) {
   left.push(arr[i]);
  } else {
   right.push(arr[i]);
  }
 }

 return quickSort(left).concat(iBase, quickSort(right));
}

var newArr = quickSort(arr);

console.log(newArr);

8:数据类型

基本数据类型:字符串类型(string)、数值类型(number)、布尔类型(boolean)、undefined、null。

1)字符串类型:必须要由成对的单引号或双引号包起来。内容可以是任意文本,只要不包含包围字符串的引号就可以。如果一定要包含,则用反斜杠转义。

// 字符串类型
var data = 'this is a string';

//字符串包含引号转义

 var data = '"this is a str'ing';

 

\0 空字节
n 换行
t 制表
b 空格
r 回车
f 进纸
\ 斜杠
' 单引号
" 双引号

  

2)数值类型:可以带小数点,也可以不带小数点。
// 数值类型
 var number = 123;
 var number = 123.4;
 var number = '123.4';

转换:

  • parseInt(..)    将某值转换成整数,不成功则NaN
  • parseFloat(..) 将某值转换成浮点数,不成功则NaN

特殊值:

  •  NaN,非数字。可以使用 isNaN(num) 来判断,切记不能用if(typeof(num)==NaN)。
  • Infinity,无穷大。可以使用 isFinite(num) 来判断。

3)布尔类型:只有两个值:true,false。

// 布尔类型 true 和 false
 var bool = true;

4)undefined:表示变量未定义。。

5)null:用来表示尚未存在的对象

**引用数据类型:对象(object),函数(function)。**

1)定义对象(冒号前面的字符串称为键,冒号后面的是值)
   var person = {name: '小明', age: 20};  //name键    小明值

2)定义数组
   var arr = ['小白', '男', 20];

3)定义函数

// 普通函数
    function func(arg){
        return true;
    }

// 匿名函数
    var func = function(arg){
        return "nick";
    }

// 自执行函数
    (function(arg){
        console.log(arg);
    })('nick')

document.write(typeof func);   //typeof来查看变量的类型

// 执行函数  

func();

自动转换

二十一、排序

1>冒泡排序 

图片 16

图片 17

// 冒泡排序:从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒
var arr = [23, 34, 11, 22, 19, 18];

/*
    冒泡排序的思路分析:
    第1轮 第1步:[23, 34, 11, 22, 19, 18]
    第1轮 第2步:[23, 11, 34, 22, 19, 18]
    第1轮 第3步:[23, 11, 22, 34, 19, 18]
    第1轮 第4步:[23, 11, 22, 19, 34, 18]
    第1轮 第5步:[23, 11, 22, 19, 18, 34]

    第2轮 第1步:[11, 23, 22, 19, 18, 34]
    第2轮 第2步:[11, 22, 23, 19, 18, 34]
    第2轮 第3步:[11, 22, 19, 23, 18, 34]
    第2轮 第4步:[11, 22, 19, 18, 23, 34]

    第3轮 第1步:[11, 22, 19, 18, 23, 34]
    第3轮 第2步:[11, 19, 22, 18, 23, 34]
    第3轮 第3步:[11, 19, 18, 22, 23, 34]

    第4轮 第1步:[11, 19, 18, 22, 23, 34]
    第4轮 第2步:[11, 18, 19, 22, 23, 34]

    第5轮 第1步:[11, 18, 19, 22, 23, 34]
*/

图片 18

for(var i = 1; i < arr.length; i  ) {
    // 内层for循环确定每轮的步数
    for(var j = 0; j < arr.length - i; j  ) {
        // 两两比较
        if(arr[j] > arr[j   1]) {
            var temp = arr[j];
            arr[j] = arr[j   1];
            arr[j   1] = temp;
        }
    }
}

2>选择排序 

图片 19

图片 20

//选择排序:两两比较,找到最大值(或者最小值)之后,将其放在正确的位置,其他数的位置不变。
/*
    选择排序的思路分析:
    第1轮 第1步:var iMinK = 0;
    第1轮 第2步:23 和 34比较,什么也不做
    第1轮 第3步:23 和 11比较,iMinK = 2
    第1轮 第4步:11 和 22比较,什么也不做
    第1轮 第5步:11 和 19比较,什么也不做
    第1轮 第6步:11 和 18比较,什么也不做
    第1轮 第7步:下标0和下标2进行位置交换 [11, 34, 23, 22, 19, 18]

    第2轮 第1步:var iMinK = 1;
    第2轮 第2步:34 和 23比较,iMinK = 2
    第2轮 第3步:23 和 22比较,iMinK = 3
    第2轮 第4步:22 和 19比较,iMinK = 4
    第2轮 第5步:19 和 18比较,iMinK = 5
    第2轮 第6步:下标1和下标5进行位置交换 [11, 18, 23, 22, 19, 34]
*/

图片 21

// 外层for循环确定轮数
for(var i = 0; i < arr.length - 1; i  ) {
    // 记录最小值的下标
    var iMinK = i;
    for(var j = i   1; j < arr.length; j  ) {
        if(arr[iMinK] > arr[j]) {
            iMinK = j;
        }
    }
    // 交换数据
    if(iMinK !== i) {
        var temp = arr[i];
        arr[i] = arr[iMinK];
        arr[iMinK] = temp;
    }
}

3>插入排序

图片 22

图片 23

在要排序的一组数中,假设前面的数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。如此反复循环,直到全部排好顺序。


/*
插入排序的思路分析:
第1轮 第1步:[23, 34, 11, 22, 19, 18]

第2轮 第1步:[23, 11, 34, 22, 19, 18]
第2轮 第2步:[11, 23, 34, 22, 19, 18]

第3轮 第1步:[11, 23, 22, 34, 19, 18]
第3轮 第2步:[11, 22, 23, 34, 19, 18]
第3轮 第3步:[11, 22, 23, 34, 19, 18]

第4轮 第1步:[11, 22, 23, 19, 34, 18]
第4轮 第2步:[11, 22, 19, 23, 34, 18]
第4轮 第3步:[11, 19, 22, 23, 34, 18]
第4轮 第4步:[11, 19, 22, 23, 34, 18]

第5轮 第1步:[11, 19, 22, 23, 18, 34]
第5轮 第2步:[11, 19, 22, 18, 23, 34]
第5轮 第3步:[11, 19, 18, 22, 23, 34]
第5轮 第4步:[11, 18, 19, 22, 23, 34]
第5轮 第5步:[11, 18, 19, 22, 23, 34]
*/

图片 24

for(var i = 1; i < arr.length; i  ) {
    // 内层的for循环
    for(var j = i; j > 0; j--) {
        if(arr[j] < arr[j - 1]) {
            var temp = arr[j];
            arr[j] = arr[j - 1];
            arr[j - 1] = temp;
        } else {
            break;
        }
    }
}

4>快速排序

 

// 选择一个基准元素,通常选择第一个元素或者最后一个元素。
//通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素。
//此时基准元素在其排好序后的正确位置,然后在用同样的方法递归的排序划分的两部分。

/*
排序数组:23, 35, 34, 11, 22, 19, 18
快速排序的思路分析:
第一步:base = 23 , arr = [35, 34, 11, 22, 19, 18]
第二步:left = [], right = []
第三步:[11, 22, 19, 18] 23 [35, 34]
第四步: [] 11 [22, 19, 18] 23 [34] 35 []
第五步:[] 11 [19, 18] 22 [] 23 [34] 35 []
第六步:[11, 18, 19, 22, 23, 34, 35]
*/

/*
if(arr.length <= 1) {
    return arr; 
}
var iBase = arr.shift();
var left = [], right = [];
for(var i = 0; i < arr.length; i  ) {
    if(arr[i] < iBase) {
        left.push(arr[i]);
    } else {
        right.push(arr[i]);
    }
}
left: [11, 22, 19, 18] iBase: 23 , right: [35, 34]

从上开始正推返回表达式:return quickSort(left即[11,22,19, 18]).concat(iBase=23, quickSort(right即[35,34]));
从下开始逆推返回值:return [11, 18, 19, 22].concat(23, [35,34]);//合并后的数组:[11,18,19,22,23,34,35]

-------------------------------------------我是单次递归分割线-----------------------------------------------

if(arr.length <= 1) {
    return arr; 
}
var iBase = arr.shift();
var left = [], right = [];
for(var i = 0; i < arr.length; i  ) {
    if(arr[i] < iBase) {
        left.push(arr[i]);
    } else {
        right.push(arr[i]);
    }
}

left: [] iBase: 11 right: [22, 19, 18]

从上开始正推返回表达式:return quickSort(left即[]).concat(iBase=11, quickSort(right即[22,19,18]));
从下开始逆推返回值:return [].concat(11, [18, 19, 22]); //合并后的数组:[11, 18, 19, 22]

-------------------------------------------我是单次递归分割线-----------------------------------------------
if(arr.length <= 1) {
    return arr; 
}
var iBase = arr.shift();
var left = [], right = [];
for(var i = 0; i < arr.length; i  ) {
    if(arr[i] < iBase) {
        left.push(arr[i]);
    } else {
        right.push(arr[i]);
    }
}

left: [19, 18] iBase: 22 right: []

从上开始正推返回表达式:return quickSort(left即[19, 18]).concat(iBase=22, quickSort(right即[]));
从下开始逆推返回值:return [18, 19].concat(22, []); //合并后的数组: [18, 19, 22]

-------------------------------------------我是单次递归分割线-----------------------------------------------

if(arr.length <= 1) {
    return arr; 
}
var iBase = arr.shift();
var left = [], right = [];
for(var i = 0; i < arr.length; i  ) {
    if(arr[i] < iBase) {
        left.push(arr[i]);
    } else {
        right.push(arr[i]);
    }
}
left: [18] iBase: 19, right: []
从上开始正推返回表达式:return quickSort(left即[18]).concat(iBase=19, quickSort(right即[]));
从下开始逆推返回值:return [18].concat(19, []); //合并后的数组: [18, 19]

*/

 

var arr = [23, 35, 34, 11, 22, 19, 18, 18];
function quickSort(arr) {
    if(arr.length <= 1) {
        return arr;
    }
    var iBase = arr.shift();
    var left = [], right = [];

    for(var i = 0; i < arr.length; i  ) {
        if(arr[i] < iBase) {
            left.push(arr[i]);
        } else {
            right.push(arr[i]);
        }
    }

    return quickSort(left).concat(iBase, quickSort(right));
}

var newArr = quickSort(arr);

console.log(newArr);

十三、三大结构

1.顺序结构

图片 25 

2.选择结构

图片 26

3.循环结构(当循环结构和直到型循环结构)

图片 27图片 28

9:运算符

算术运算符: 、-、*、/、%(取余)、 (递增)、--(递减)

   // 运算符:可用于把字符串变量连接起来。

   var  a=1 "5"  //结果为15(字符串)

// 加号的另一种用法:如果加号的两侧,有一个是字符串则结果是字符串的拼接。
 var a = 4, b = '7';
 document.write(a   (b - 3));  //值为8

//当用/运算符的时候,Math.round的用法(四舍五入)。
 var a = 9 ,b = 7;
// Math.round:四舍五入到整数位  表达式Math.round(9/7)=1,如果想四舍五入到某小数位则先乘后除
 var c = Math.round(9 / 7 * 100) / 100;
 document.write(c);

 //parseInt:将字符串转换成整数。

 //parseFloat:将字符串转换成浮点数。

 // parseInt:将字符串转换成整数,从字符串左侧依次查找数值,直到碰到非数值的字符结束

 // parseFloat:将字符串转换成浮点数(带有小数点的数值)。

// NaN:not a number

var a = '0.128.6.7px';
var b = parseInt(a);     //b=0
var b = parseFloat(a);  //b=0.128
document.write(b);

  

// 算数运算符%(取余)
 var a = 10.4, b = 7;
//var c = a% b ;//按照正常算法3.4,但是js定义的变量都是弱类型,精度相对来说较低出来的结果大概是3.400000000000000000004,这个样子,结果接近我们处理的方式如下:

 var c = a  * 10 % b / 10;

 document.write(c);

  

//    (自增) => 前自增(  a)、后自增(a  )

 var a = 5;

// a的前自增:变量本身先自增1,然后再将结果赋予当前位置

// a的后自增:变量的值先赋予当前位置,然后变量本身再自增1

 var b = 4   a  ;

 document.write(a); // 6
document.write(b); // 9

--a和a--原理同 a和a

var a = 4, b = 3;
var c = (a       b   b--   --a) % 5;
//表达式对应值:4 4 4 4
//对应位置a、b的值: a  =5、  b=4、 b--=3、--a=4 
document.write(c); //
document.write(a); //
document.write(b); //    

赋值运算符:=、 =、-=、*=、/=、%=

var a = 4, b = 5;
a  = b; // a = a   b;
a %= b; // a = a % b;
document.write(a);
document.write(b);

  

关系(比较)运算符:>、<、>=、<=、==、===、!=、!==

===与==的区别:

对于string和number等基本类型,不同类型之间比较,==比较会将变量隐式转换成同一类型的值进行比较。而===如果类型不同,其结果就是不等。

如果是array和object等引用类型,==和===没有区别,如果两个的变量是同一个对象就为true,否则为false。

基本类型和引用类型进行比较,==会将引用类型转换成基本类型,再进行值比较。而===因为类型不同,结果为false。

// == 和 ===

// 基本数据类型
 var a = 5, b = '5';

 document.write(a == b); //true
 document.write(a === b);//fasle


// 引用数据类型:看两侧的变量是否为同一个对象,是则true,不是则false
 var a = {}, b = {};

 document.write(a == b); //false
 document.write(a === b); //false

  

逻辑运算符:&&、||、!

图片 29

 

三目运算符:? :

// 三目运算符:condition ? if_true : if_false;

var c = 5 > 4 ? '恩' : '哦';
 alert(c);  //c=恩

 

使用Boolean函数,可以将任意类型的变量转为布尔值。

1>Number强制转换

十五、函数

函数的概念:函数就是把完成特定功能的一段代码抽象出来,使之成为程序中的一个独立实体,起个名字(函数名)。可以在同一个程序或其他程序中多次重复使用(通过函数名调用)。
注:编写好的函数代码只有通过调用才会执行,不调用的时候不会执行(自执行函数特例)。
函数的作用(好处):
1,使程序变得更简短而清晰
2,有利于程序维护
3,可以提高程序开发的效率 ,
4,提高了代码的重用性(复用性)

1>函数的创建方式

// 函数声明式的方式创建函数
  function funcName() {}

// 函数表达式的方式创建函数
  var funcName = function () {};

// 通过构造函数的方式创建函数
// 构造函数:出现在new运算符后的函数,称为构造函数
  var funcName = new Function ();

函数声明式和函数表达式的区别

// 函数声明式的方式必须指定函数名
function sum() {
 alert(1);
}
sum();
// 函数表达式的方式可以没有名字
 (function () {
 alert(1);
 })();

2>函数的调用方式

 //创建函数
function hello() {
   document.write('hello ');
   document.write('world ');
 } 
// 方式1:手动调用
 hello();
// 方式2:事件驱动的方式
 var oBox = document.getElementById('box');
oBox.onclick = function () {
   hello();
 };

3>函数的参数(形参和实参)

1.手动传递的形参和实参

//函数定义时,定义的变量为形参:a,b
function sum(a, b) {
    alert(a   b);
}
//函数调用时,传递的参数值为实参:4,8
sum(4, 8);

补充:对象中,冒号前面的数据可以称为键、下标、或者key,冒号后面的值称为值或者value

2.JS解析器内置定义的arguments (在函数内部的内置的对象参数,无需自定义可直接使用)

 arguments 值类型(对象类型),包含的是实参的个数和数据

function sum(a, b) {
// 通过下标的方式获取某一个值
console.log(arguments[0]);
// 通过遍历的方式获取所有的值(下标0起始)
for(var i = 0; i < arguments.length; i  ) {
    console.log(arguments[i]);//分别控制台打印5,3,8
}
a  ;
//a和arguments[0]和指向相同结果可想而知,相同为6

console.log(arguments[0]);//6 
console.log(a);//6 } //手动调用函数 sum(5, 3, 8); 

3.return(返回函数执行的结果) 

 // return关键词
 function sum(a, b) {
  var c = a   b;
  return c;/*!return只能返回参数只能有一个。return a,b,c 最终返回的结果是c的结果,不会报错*/
  /*!return 后面的代码不会执行*/
  alert('hello world!');//永远不会被执行
  // 函数默认返回的值是undefined
 }
 var d = sum(4, 7);
 console.log(d);

6:js变量

变量是存储信息的容器,用var关键词来声明(创建)变量。

1)变量定义(声明):

先定义后赋值:

var age;    //var 是关键字,age是变量名

age = 20;  //20是数据 “=”是赋值

定义的同时赋值: var age=20;

一条语句中声明多个变量,该语句以var开头,并使用英文逗号分隔。

var x= '加数', y= '加数',z='和';

2)局部变量必须以 var 开头申明,如果不写 var 则为全局变量 

<script type="text/javascript">

    // 全局变量
    name = 'xiaoming';

    function func(){
        // 局部变量
        var age = 18;

        // 全局变量
        sex = "man"
    }
</script>

 

注:1, 变量也可以不定义,但强烈不推荐。 2, 变量必须先赋值再使用


 7:变量命名规则及常用命名法

1)变量命名规则:以字母、数字、下划线和$组成,但是不能以数字开头。且JS语句和JS变量都是严格区分大小写不能用拼音来命名。

2)变量常用命名法**推荐西班牙命名法,以 小写字母b,f,i,s开头表示类型,后接大写开头的有意义的单词。**

驼峰命名法(Camel):第一个单词的首字母小写,后面的单词首字母大写。

帕斯卡命名法(Pascal):所有单词的首字母大写。

匈牙利命名法(Hungarian):在变量名最前面添加相应小写字母来标识变量的类型,后面的单词首字母大写。

 

图片 30

// 驼峰命名法
// var haveGoodGoods = '有好货';

// 帕斯卡命名法
// var HaveGoodGoods;

// 匈牙利命名法
// var sHaveGoodGoods = '有好货';

 3)尽量使用有意义的单词作为变量名(语义化),也尽量不要与HTML、CSS中的关键字冲突。**

                  保留关键字列表

图片 31


 

上面代码相当于下面这样。

附录:

进制间的转换(二进制、八进制、十进制、十六进制)

1>10进制转换为16进制:(10).tostring(16)

2>8转16:(012).tostring(16)

3>16转10:(0x).tostring(10)

4>10转2:(111111).tostring(2)

5>16转8:(0x16).tostring(8)

6>parseInt(10,2)

7>parseInt(12,16)

8>parseInt(12,8)

参数为原始类型值的转换规则:

原始类型的值主要是字符串、布尔值、undefined和null,它们都能被Number转成数值或NaN。

NaN:not a number,当数学计算得不到数字结果时,该值就是NaN(Number类型)。

isNaN:判断变量是否为NaN。


 1、JavaScript 基础一  (从零学习JavaScript)    

2、JavaScript 基础二 (从零学习JavaScript)


借鉴转载出处: http://www.cnblogs.com/witkeydu/

七、变量命名规则及常用命名法 

  **1)变量命名规则:以字母、数字、下划线和$组成,但是不能以数字开头。且JS语句和JS变量都是严格区分大小写不能用拼音来命名。**

  2)变量常用命名法**推荐西班牙命名法,以 小写字母b,f,i,s开头表示类型,后接大写开头的有意义的单词。**

驼峰命名法(Camel):第一个单词的首字母小写,后面的单词首字母大写。

帕斯卡命名法(Pascal):所有单词的首字母大写。

匈牙利命名法(Hungarian):在变量名最前面添加相应小写字母来标识变量的类型,后面的单词首字母大写。 

图片 32

// 驼峰命名法 //

var haveGoodGoods = '有好货';

// 帕斯卡命名法

 var HaveGoodGoods;

// 匈牙利命名法

 var sHaveGoodGoods = '有好货';

  

 3)尽量使用有意义的单词作为变量名(语义化),也尽量不要与HTML、CSS中的关键字冲突。**

                  保留关键字列表

图片 33

12:自动转换

自动转换的规则:预期什么类型的值,就调用该类型的转换函数。比如,某个位置预期为字符串,就调用String函数进行转换。如果该位置即可以是字符串,也可能是数值,那么默认转为数值。

由于自动转换具有不确定性,而且不易除错,建议在预期为布尔值、数值、字符串的地方,全部使用Boolean、Number和String函数进行显式转换。

1:自动转换为布尔值

当JavaScript遇到预期为布尔值的地方(比如if语句的条件部分),就会将非布尔值的参数自动转换为布尔值。系统内部会自动调用Boolean函数。

if ( !undefined && !null && !0 && !NaN && !'' ) { console.log('true'); } // true

// 写法一 expression ? true : false

// 写法二 !! expression

2:自动转换为字符串

当JavaScript遇到预期为字符串的地方,就会将非字符串的数据自动转为字符串。系统内部会自动调用String函数。字符串的自动转换,主要发生在加法运算时。当一个值为字符串,另一个值为非字符串,则后者转为字符串。

'5' 1 // '51'                  '5' true // "5true"

'5' false // "5false"          '5' {} // "5[object Object]"

'5' [] // "5"                  '5' function (){} // "5function (){}"

'5' undefined // "5undefined“

 '5' null // "5null"

3:自动转换为数值

当JavaScript遇到预期为数值的地方,就会将参数值自动转换为数值。系统内部会自动调用Number函数。

'5' - '2' // 3                  '5' * '2' // 10

true - 1 // 0                   false - 1 // -1

'1' - 1 // 0                    '5' * [] // 0

false / '5' // 0                'abc' - 1 // NaN

除加法运算符有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值。

'abc' // NaN         -'abc' // NaN              true // 1             -false // 0

 

特殊:

null == undefined   // true

null == false        // false

undefined == false // false


如果,第一个空对象不被JavaScript视为空代码块,就会得到“[object Object][object Object]”的结果。

十三、三大结构

1.顺序结构

图片 34 

2.选择结构

图片 35

3.循环结构(当循环结构和直到型循环结构)

图片 36图片 37

十一、强制转换

强制转换主要指使用Number、String和Boolean三个构造函数,手动将各种类型的值,转换成数字、字符串或者布尔值。

1>Number强制转换

参数为原始类型值的转换规则:

原始类型的值主要是字符串、布尔值、undefined和null,它们都能被Number转成数值或NaN。

NaN:not a number,当数学计算得不到数字结果时,该值就是NaN(Number类型)。

isNaN:判断变量是否为NaN。

Number(324) 值:324 字符串如果可以被解析为数值,则转换为相应的数值
Number('324abc')  值:NaN 字符串:如果不可以被解析为数值,返回NaN
Number('')  值:0 空字符串转为0
Number(true) 、Number(false) 值:1、0 布尔值:true 转成1,false 转成0
Number(undefined) 值:NaN undefined:转成 NaN
Number(null) 值:0 null:转成0

Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN。

参数为对象的转换规则:简单的规则是,Number方法的参数是对象时,将返回NaN。

Number({a: 1}) // NaN

Number([1, 2, 3]) // NaN

实际上,Number背后的真正规则复杂得多,内部处理步骤如下:

1:调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。

2:如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。

3:如果toString方法返回的是对象,就报错。

2>String强制转换

参数为原始类型值的转换规则:

    • 数值:转为相应的字符串。
    • 字符串:转换后还是原来的值。
    • 布尔值:true转为"true",false转为"false"。
    • undefined:转为"undefined"。
    • null:转为"null"。

参数为对象的转换规则:String方法的参数如果是对象,返回一个类型字符串;如果是数组,返回该数组的字符串形式。

String内部处理步骤如下:

1:先调用对象自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。

2:如果toString方法返回的是对象,再调用valueOf方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。

3:如果valueOf方法返回的是对象,就报错。

3>Boolean强制转换

参数为原始类型值的转换规则:转换规则相对简单:除了以下六个值的转换结果为false,其他的值全部为true。

undefined、null、-0、0或 0、NaN、''(空字符串)

参数为对象的转换规则:所有对象(包括空对象)的转换结果都是true。 

4:文件引入

 <script>标签用于定义客户端脚本。它既可以包含脚本语句,也可以通过src属性指定外部脚本文件。

属性:

language:用来指定<script>标签中的脚本类型,即javascript。已废弃,大多数浏览器已经忽略它了,所以不要在使用。

type:它也是用来指定<script>标签中的脚本类型,即text/javascript。它也是type的默认值,所以可以忽略指定。

src:指定外部的脚本文件。如果指定该属性,script标签包含的JS脚本不会执行。

不可以使用单标签,即<script type=“text/javascript”/>。

1) 引入外部文件

<script type="text/javascript" src="JS文件"></script>

2.存放在HTML的<head>或<body>中

<script type="text/javascript">
    Js代码内容
</script>
  • HTML的head中
  • HTML的body代码块底部(推荐)

3) 为什么要放在<body>代码块底部?

  • HTML代码从上到下执行,先加载CSS,避免html出现无样式状态;
  • 将JavaScript代码块放在<body>最后,可以让网页尽快的呈现给用户,减少浏览者的等待时间,避免因为JS代码块阻塞网页的呈现。


如果要将对象转为字符串,则是采用以下步骤。

参数为对象的转换规则:String方法的参数如果是对象,返回一个类型字符串;如果是数组,返回该数组的字符串形式。

十九、常用函数类型

1>回调函数(指针:通过函数名称的方式执行的函数) 

*function sum(a, b, fn) {
 var c = a   b;
 if(c > 9) {
  fn();
 }
 console.log(c);
}


sum(7, 5, function () {
 alert(1);
});

 2>递归函数(自身调用自身的函数) 

/*
递归函数调用分析:
 {
  var num = 1;
  num  ; // 2
  if(num < 5) {
   {
    var num = 2;
    num  ; // 3
    if(num < 5) {
     {
      var num = 3;
      num  ; // 4
      if(num < 5) {
       {
        var num = 4;
        num  ; // 5
        if(num < 5) {
         print(num);
        }
        console.log(num); // 5
       }
      }
      console.log(num);
     }
    }
    console.log(num);
   }
  }
  console.log(num);
 }
*/

function print(num) {
 num  ;
 if(num < 5) {
  print(num);
 }
 console.log(num);
}

print(1);

 3>匿名函数

(function () {})();

4>构造函数

function Person() {
 alert(1);
}

var obj = new Person();

console.log(obj);

 

如果toString方法返回的不是原始类型的值,结果就会报错。

十四、JavaScript语句

(一)选择语句

1)if语句

(1)单一选择结构:if(){}  

var x=5,y=8; if(y>x) {   alert("x>y");}

(2)二路选择结构:if(){}else{} 

// 判断:如果第一个值大于第二个值则alert(OK!)
var x=5,y=8;
if(y> x){
   document.write('OK!');
}
else{
  document.write('NOT OK!');
}  

(3)三目运算符:?: (condition ? if_true : if_false;) 

var x=5,y=8; alert(x> y? 'OK!' : 'NOT OK!')

(4)多路选择结构:if(){}else if(){}else if(){}else{}

多路选择结构流程图:

图片 38

//此处给出主要代码为例
   if(sScore >= 0 && sScore < 60) {
        alert('不及格,平常干啥啦!');
    } else if(sScore >= 60 && sScore < 70) {
        alert('刚刚及格,继续努力!');
    } else if(sScore >= 70 && sScore < 80) {
        alert('一般,再接再厉!');
    } else if(sScore >= 80 && sScore < 90) {
        alert('良好,稳住,你可以的!');
    } else if(sScore >= 90 && sScore < 100) {
        alert('优秀,戒骄戒躁,争取满分!');
    } else if(sScore == 100) {
        alert('劳逸结合,注意身体!');
    } else {
        alert('分数非法!');
   }

2)switch语句(考虑多路选择的案例转换为switch实现,提示:case后的是具体的情况,多路选择是以表达式的方式进行判断,即点和面的关系。如:80-90范围这个面通过除以10,然后通过parseInt进行取整。(面转成点))

语法:switch(condition){case :break;default:}

break具体讲解:阻止代码向下一个case运行。防止case穿透(穿透性用的好还是挺6的,有时间后续补充案例:给定依据具体日期得出这是本年的第多少天的案例)。
default具体讲解:匹配不存在时做的事情。
switch:严格检查类型(形似===的检查),如果不统一,条件不成立(比如说数字的字符串和case后的Number后的数字无法匹配,需转成相同的类型)

// 判定
switch(iWeekday){
  //利用穿透性
  case 0:
  case 7:
    alert('星期天');
    break;
  case 1:
    alert('星期一');
    break;
  case 2:
    alert('星期二');
    break;
  case 3:
    alert('星期三');
    break;
  case 4:
    alert('星期四');
    break;
  case 5:
    alert('星期五');
    break;
  case 6:
    alert('星期六');
    break;
  default:
    alert('非法数据!');
}

 (二)循环语句

1)for循环语句

// for循环语法
/*
    for(var i = 0; i < 10; i  ){
        code...
    }
*/

for(var a = 4; a < 10; a  ) {
    document.write(a);
}

// for循环的嵌套
for(var i = 0; i < 5; i  ) {
    for(var j = 0; j < 5; j  ) {
        document.write(i*j   '、');
    }
    document.write('<br>');
}

2)for in语句(可以遍历数组和对象,经常用于遍历对象)

遍历数组

var names = ["nick", "jenny"];

for(var index in names){
    console.log(index);
    console.log(names[index]);
}

遍历对象 

var obj = {name: '张三', age: 24, hobby: ['打篮球', '搏击', '打乒乓球']};
for(var attr in obj) {
    console.log(obj[attr]);
}

3)while循环语句

/*
  while语法
while(condition){
  code...
}
*/
var a = 4;

while(a < 10) {
    document.write(a);
    a  ;
}

4)do-while语句 

/*
do...while语法
do{
  code...
}while(condition);
*/
var a = 4;
do{
  document.write(a);
  a  ;
}
while(a < 10);
// while和do...while的区别:执行的顺序不一样
//do...while至少会执行一次代码块,while有可能一次都不执行。

(三)Label语句 

//label语句   跳出双重循环   例:条件 i=5 j=5 时  跳出嵌套的双重for循环   num=55;
var num = 0;
    outPoint:
    for (var i=0;i<10;i  ) {
        for (var j=0;j<10;j  ) {
            if (i==5 && j==5) {
                break outPoint;
            }
            num  ;
        }
    }
    console.log(num); //控制台输出

(四)异常处理 

try {
    //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行
}
catch (e) {
    // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。
    //e是一个局部变量,用来指向Error对象或者其他抛出的对象
}
finally {
     //无论上述代码怎么,finally代码块始终会执行
}

补充:break和continue的区别 

// break和continue
for(var i = 0; i < 10; i  ) {
    if(i === 5) {
        break;
    }
    document.write(i);
}
for(var i = 0; i < 10; i  ) {
    if(i === 5) {
        continue;
    }
    document.write(i);
}
// 区别:break终止循环,continue跳过当前循环。
// 共同点:都不会执行后面的代码

二十、数组 

定义:数组是一个可以存储一组或一系列相关数据的容器。

为什么要使用数组?

   1:为了解决大量相关数据的存储和使用的问题。

   2:模拟真实的世界(班级、军队)。

1>数组的操作

1)创建数组

  (1)构造函数的方式:var a=new Array();

  (2)隐式声明的方式:var b=[];

2)数组的赋值

构造函数函数的方式

(1)直接赋值:var a=new Array(数据1,数据2,…);

    注:var a=new Array(数值)       如果括号中只有一个元素,并且这个元素是数值类型的,那么他就是指定数组的长度。 并且它的值都是undefined。

  数组的属性:length 属性(获取整个数组的长度)。

(2)先声明后赋值:var a=new  Array(); a[0]=1;  a[1]=2;  a[2]=3;

隐式声明赋值

(1)直接赋值: var a=[1,2,3,4];

(2)声明以后再赋值: var a=[]; a[0]=1;  a[1]=2;  a[2]=3;

注:JS数组可以存储任何类型的值。eg: arr[3] = function () {}; 

3)访问数组 

  通过数组的(中括号)下标访问。 

    arr[0-(length-1)] //数组下标从0开始,他的最大值,是length-1。

  arr['name'] //关联数组 通过下表字符串进行访问

4) 修改数据:arr[3] = '修改的数据';

5)删除数据:delete arr[1]; 

6)遍历数组

1:for循环。

for(var i = 0; i < arr.length; i  ) {
  console.log(arr[i]);
}

2:while循环。

var i = 0;
while(i < arr.length) {
  console.log(arr[i]);
  i  ;
}  

3:for in循环。(遍历数组不常用)

  数组的遍历。

for(var attr in arr){

  //attr 数组的下标

  console.log(arr[attr])

}

  对象属性的遍历。

  // 使用for in 遍历对象

  var obj = {name: '小明', age: 24, hobby: ['打篮球', '搏击', '打乒乓球']};

  for(var attr in obj) {
    console.log(obj[attr]);
  }

2>数组分类

1:按照下标的类型

     1.下标是数字的类型叫做(索引数组)

  var arr = ['1', '2' , '3']; 

     2.下标是字符串类型叫做(关联数组),必须通过对象模拟的形式才能实现,一般不用。

var arr = [];
arr['name'] = '张三';
arr['age'] = '28';

2:按照维度来分类

  1.一维数组常用的数组就是一维数组

  2.二维数组,通过对象模拟的形式才能实现。

  声明二维数组:

  var arr=[[1,2,3],[4,5,6]];    alert(arr[1][1]); //值5

3>数组的属性 

(1)length: 设置或返回数组元素的数目。(可读可写)

length属性控制数组的读:console.log(arr.length-1);

length属性控制数组的写:arr.length = 6; 

(2)constructor:返回构造函数的引用。(输出constructor的返回值:Array)

4>数组的方法(加粗常用)

  前五个对原始对象的操作

1. arr.push(数组元素1,数组元素2,........)   向数组的末尾加入新元素 | 返回值:新数组的长度

 eg:arr.push('追加元素1','追加元素2');

2.arr.unshift(数组元素1,数组元素2,........)  向数组的开头加入新元素 | 返回值是新数组的长度。

 eg:arr.unshift(开头新元素1,开头新元素2)

3. arr.pop()    删除数组的最后一个元素 | 返回值是删除的元素。 

var first = arr.pop();

4. arr.shift()  删除数组的第一个元素 | 返回删除的元素。

var first = arr.shift();

5.万能的添加删除函数 arr.splice(index,数量,添加的元素.....)  注:前俩个元素必须有 

   (1)index   从何处开始添加或删除,必须是数值类型(数组的下标) 

   (2)数量    规定了删除的个数,如果是0,则不删除。 

   (3)需要添加的元素,可以当作替换的元素。 

   (4)如果有删除的元素,以数组的方式返回删除的元素。 

// 添加元素
arr.splice(2, 0, '王五');
// 修改元素
arr.splice(1, 1, '王五');
//修改与添加
arr.splice(1, 1, '王五','李四');
// 删除元素 
var del = arr.splice(1, 1); 

 6.arr.join([分隔符])   把数组元素按照指定分隔符组合成一个字符串,如果没有指定分隔符,默认是用“,”分割 | 返回结果就是组合成的字符串。   

var param = {
 q: '棉衣',
 commend: 'all',
 search_type: 'item'
};

var aParam = [];
for(var attr in param) {
 aParam.push(attr   '='   param[attr]);
}
console.log(aParam.join('&'));  //以字符&分割连接数组
//结果:q=棉衣&commend=all&search_type=item

  7.arr.slice()  数组的分割。从截取指定的开始位置,到结束位置(不包括)的元素。如果不指定结束位置,则从指定的开始位置,取到结尾(数组的下标)。 

支持负数(-1开头)  返回的是新数组。 不改动原来的数组。正数和负数都是向右查找 

var arr = ['宋江', '卢俊义', '武松', '杨雄', '石秀', '鲁智深'];
var newArr = arr.slice();相当于拷贝数组
var newArr = arr.slice(2);//不指定结束为止,默认为截取到最后
var newArr = arr.slice(2, 5);//结果为下标为2、3、4的数组元素,不包含为指定结尾下标数的元素
var newArr = arr.slice(-2, -1);  //从末尾开始计数分割  只能按照从左向右的顺序进行截取,即不支持arr.slice(-1, -2)   结果:'石秀'
  1. arr.concat()   连接两个或更多的数组,并返回新数组,对原数组没有任何影响。 

eg:arr1.concat(arr2)  //将数组arr1和arr2连接成新数组返回

9.arr.reverse()  数组翻转方法。改变原数组 

arr.reverse(arr)  //将数组翻转

 

10.arr.sort()   对数组进行排序,如果没有参数,则按照字母的编码进行排序,如果要按照其他的顺序来排序,要提供一个函数。

回调函数会提供两个参数(a,b)。

 

a<b  a在b前。

a=b  顺序按照原样输出。

a>b  b在a前。 

eg:

['d', 'c', 'b', 'a'].sort()  // ['a', 'b', 'c', 'd'] 

[4, 3, 2, 1].sort()  // [1, 2, 3, 4] 

[11, 101].sort()  // [101, 11] 

[10111, 1101, 111].sort()  // [10111, 1101, 111] 

如果想让sort方法按照自定义方式排序,可以传入一个函数作为参数,表示按照自定义方法进行排序。该函数本身接受两个参数,表示进行比较的两个元素。如果返回值大于0,表示第一个元素排在第二个元素后面;其他情况下,都是第一个元素排在第二个元素前面。

返回值正直交换   零、负值不交换  负值降序   正值升序

 [10111, 1101, 111].sort(function (a, b) { 

     return a - b; //回调函数

})   //输出结果: [111, 1101, 10111] 

[ { name: "张三", age: 30 }, { name: "李四", age: 24 }, { name: "王五", age: 28 } ].sort(function (o1, o2) { 

    return o1.age - o2.age;

})   // [ { name: "李四", age: 24 }, { name: "王五", age: 28 }, { name: "张三", age: 30 } ] 

10:运算符的优先级

. [] ():字段访问、数组下标、函数调用以及表达式分组

、--、!、delete、new、typeof

*、/、%

、-、   加、减、字符串连接

关系运算符、instanceof(判断某个对象是否是某个类的一个实例)

逻辑运算符

赋值运算符

()作用:可以表达式分组、改变运算符的优先级、函数调用。

new运算符:用来创建对象。


 

对非布尔值类型的数据求布尔值;

  • 原始类型的值主要是字符串、布尔值、undefined和null,它们都能被Number转成数值或NaN。
  • NaN:not a number,当数学计算得不到数字结果时,该值就是NaN(Number类型)。
  • isNaN:判断变量是否为NaN。

八、数据类型

  • 基本数据类型:字符串类型(string)、数值类型(number)、布尔类型(boolean)、undefined、null。

1)字符串类型:必须要由成对的单引号或双引号包起来。内容可以是任意文本,只要不包含包围字符串的引号就可以。如果一定要包含,则用反斜杠转义。

// 字符串类型
var data = 'this is a string';

//字符串包含引号转义

 var data = '"this is a str'ing'; 

\0 空字节 n 换行 t 制表 b 空格 r 回车 f 进纸 \ 斜杠 ' 单引号 " 双引号  

 

2)数值类型:可以带小数点,也可以不带小数点。
 var number = 123;
 var number = 123.4;
 var number = '123.4';

转换:

parseInt(..)    将某值转换成整数,不成功则NaN

parseFloat(..) 将某值转换成浮点数,不成功则NaN

特殊值:

   NaN,非数字。可以使用 isNaN(num) 来判断,切记不能用if(typeof(num)==NaN)。

  Infinity,无穷大。可以使用 isFinite(num) 来判断。

 

3)布尔类型:只有两个值:true,false。

// 布尔类型 true 和 false
 var bool = true;

 

4)undefined:表示变量未定义。

 

5)null:用来表示尚未存在的对象

  • **引用数据类型:对象(object),函数(function)。**

1)定义对象(冒号前面的字符串称为键,冒号后面的是值)
   var person = {name: '小明', age: 20};  //name键    小明值 

2)定义数组
   var arr = ['小白', '男', 20]; 

3)定义函数(此处数据类型不进行深究)

// 普通函数(声明式创建函数)
 function func(arg){
     return true;
 } 
// 匿名函数 (表达式创建函数)
var func = function(arg){ 
    return "nick"; 
} 
// 自执行函数 
(function(arg){ 
    console.log(arg); 
})('nick')

// 通过构造函数的方式创建函数

// 构造函数:出现在new运算符后的函数,称为构造函数

var funcName = new Function ();
document.write(typeof func);   //typeof来查看变量的类型

// 执行函数 

func();

1:定义:javascript是一种弱类型、动态类型、解释型的脚本语言。

弱类型:类型检查不严格,偏向于容忍隐式类型转换。

强类型:类型检查严格,偏向于不容忍隐式类型转换。

动态类型:运行的时候执行类型检查。

静态类型:编译的时候就知道每个变量的类型。

解释型:程序不需要编译,程序在运行的时候才翻译成机器语言,每执行一次都要翻译一次,因此效率比较低,但是跨平台性好。

编译型:程序在执行之前需要一个专门的翻译过程,把程序编译为机器语言的文件,运行时直接使用编译的结果就行了。

标记语言:标记语言的存在就是用来被读取(浏览)的,而其本身是没有行为能力的,在标记语言里你会看到<和>这些尖括号,这是用来写出“层次”和”属性”的,换句话说,它是被动的。并不具备与访问者互动的能力。

编程语言:它是具有逻辑性和行为能力,这是主动的。说通俗一点,它是有思想的。

脚本语言:它介于标记语言和编程语言之间,脚本语言不需要编译,可以直接用,由解释器来负责解释。


 2:JS历史 

1)Netsape发明了javascript。

1994年,网景公司(Netscape)发布了Navigator浏览器0.9版。这是历史上第一个比较成熟的网络浏览器,轰动一时。但是这个版本的浏览器只能用来浏览,不具备与访问者互动的能力。比如,网页上有
一栏用户名需要填写,浏览器无法判断用户是否真的填写了,只有让服务器去判断。如果没有填写就返回错误,要求用户重新填写。太浪费时间和服务器资源了。更何况在那个用调制解调器上网的年代

 

2)JS之父Brendan Eich(布兰登 · 艾奇)

网景公司急需一种网页脚本语言,使得浏览器可以与网页互动。当时工程师Brendan Eich就是负责开发这种新语言。

 

图片 39

 

3)为什么叫JavaScript

1995年Sun公司将Oak语言改名为Java,正式向市场推出。Sun公司大肆宣传,允诺这种语言可以”一次编译,到处运行”。很有可能成为未来市场的主宰。
网景公司动了心,决定与Sun公司结成联盟。它不仅允许JAVA程序以applet(小程序)的形式,直接在浏览器中运行。甚至还考虑直接将Java作为脚本语言嵌入网页,只是因为这样使HTML网页过于复杂,
后来才不得不放弃。
总之,因为Sun公司完全介入网页脚本语言的决策。Js后来就是网景公司和Sun两家公司一起携手推向市场的,这种语言被命名为java script不是偶然的。

 

 

4)JS和JAVA语言没有任何关系

JS之父并不喜欢JAVA,为了应付公司安排的任务,他只用了十天就把JS设计出来了。因为设计时间太短,语言的一些细节考虑的并不太严谨。
设计思路:
1:借鉴C语言的基本语法。
2:借鉴JAVA语言的数据类型和内存管理。
3:借鉴Scheme语言,将函数提升到”第一等公民的地位”。
4:借鉴Self语言,使用基于原型(prototype)的继承机制。
所以,JS实际是两种语言风格的混合产物:(简化的)函数式编程 (简化的)面向对象编程。

 

5)JS标准化---ECMAScript

因为javascript1.0的成功,netscape在navigator 3.0中发布1.1版。此时微软决定进军浏览器,在IE3.0种搭载了javascript的克隆版,叫JScript。在微软进来以后,有三种不同的javascript版本存在,即navigator3.0的javascript、IE的JScript、以及Cenvi中的ScriptEase。
由于javascript没有一个标准来统一其语法和特性,3种不同版本的恰恰突出了这个问题,这个语言的标准化显然势在必行。
1997年,javascript1.1作为一个草案提交给欧洲计算机制造协会(ECMA)。最后定义为ECMAScript的全新脚本语言。从此,浏览器开始努力将ECMAScript作为Javascript的基础。

 3:JS组成

强制转换

String内部处理步骤如下:
1:先调用对象自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
2:如果toString方法返回的是对象,再调用valueOf方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
3:如果valueOf方法返回的是对象,就报错

十八、值传递和址传递(引用传递)

  •  值传递:如果变量的值是基本数据类型,那么传递值的时候采用的是值传递(把值复制一份给另外一个变量)。
  •  址传递:如果变量的值是引用数据类型,那么传递值的时候采用的是址传递(把地址复制一份给另外一个变量)。
  • 相关联想函数指针(地址)
  •  值类型和引用类型内存存储的位置分为栈(小区域少量数据)和堆(大片区域大量数据) 

    //值类型(值相同,重新开辟内存空间) var a= 10; var b = a; a = 0; console.log(b);//10

    //引用类型(地址相同,一起变) var a = {num: 10}; var b = a; a.num = 0; console.log(b.num);//0

 图片 40 

var a = {
 name: '张三'
};
var b = {
 name: a
};

var c = b;

var d = {
 name: '李四'
};

c.name = d;

console.log(b.name.name);//张三  

注释可用于提高代码的可读性。Javascript不会执行注释,用户也不会看到注释,注释只是方便开发者更好的理解JS代码。

单行注释:以//开头。

// 这是一行单行注释

 

多行注释:以/*开头,以*/结尾。 

/*
    第一行注释
    第二行注释
*/

文档注释:以/**开头,以*/结尾。

 

/**
    这是文档的注释
*/

重要注释:以/*!开头,以*/结尾 

/*!
    这是非常重要的注释
*/

数值:转为相应的字符串。

十八、值传递和址传递(引用传递)

  •  值传递:如果变量的值是基本数据类型,那么传递值的时候采用的是值传递(把值复制一份给另外一个变量)。
  •  址传递:如果变量的值是引用数据类型,那么传递值的时候采用的是址传递(把地址复制一份给另外一个变量)。
  • 相关联想函数指针(地址)
  •  值类型和引用类型内存存储的位置分为栈(小区域少量数据)和堆(大片区域大量数据)
//值类型(值相同,重新开辟内存空间)
var a= 10;
var b = a;
a = 0;
console.log(b);//10

//引用类型(地址相同,一起变)
var a = {num: 10};
var b = a;
a.num = 0;
console.log(b.num);//0

 

 图片 41

var a = {
    name: '张三'
};
var b = {
    name: a
};
var c = b;
var d = {
    name: '李四'
};
c.name = d;
console.log(b.name.name);//张三

二、JS由来及其发展史

1)Netsape发明了javascript。 

图片 42图片 43

1994年,网景公司(Netscape)发布了Navigator浏览器0.9版。这是历史上第一个比较成熟的网络浏览器,轰动一时。但是这个版本的浏览器只能用来浏览,不具备与访问者互动的能力。比如,网页上有一栏用户名需要填写,浏览器无法判断用户是否真的填写了,只有让服务器去判断。如果没有填写就返回错误,要求用户重新填写。太浪费时间和服务器资源了。更何况在那个用调制解调器上网的年代

Javascript历史

2)JS之父Brendan Eich(布兰登 · 艾奇) 

图片 44图片 45

网景公司急需一种网页脚本语言,使得浏览器可以与网页互动。当时工程师Brendan Eich就是负责开发这种新语言。

Javascript历史

图片 46

 3)为什么叫JavaScript

图片 47图片 48

1995年Sun公司将Oak语言改名为Java,正式向市场推出。Sun公司大肆宣传,允诺这种语言可以”一次编译,到处运行”。很有可能成为未来市场的主宰。
网景公司动了心,决定与Sun公司结成联盟。它不仅允许JAVA程序以applet(小程序)的形式,直接在浏览器中运行。甚至还考虑直接将Java作为脚本语言嵌入网页,只是因为这样使
HTML网页过于复杂,后来才不得不放弃。
总之,因为Sun公司完全介入网页脚本语言的决策。Js后来就是网景公司和Sun两家公司一起携手推向市场的,这种语言被命名为java script不是偶然的。

Javascipt历史

 

4)JS和JAVA语言没有任何关系

图片 49图片 50

JS之父并不喜欢JAVA,为了应付公司安排的任务,他只用了十天就把JS设计出来了。因为设计时间太短,语言的一些细节考虑的并不太严谨。
设计思路:
1:借鉴C语言的基本语法。
2:借鉴JAVA语言的数据类型和内存管理。
3:借鉴Scheme语言,将函数提升到”第一等公民的地位”。
4:借鉴Self语言,使用基于原型(prototype)的继承机制。
所以,JS实际是两种语言风格的混合产物:(简化的)函数式编程 (简化的)面向对象编程。

Javascript历史

5)JS标准化---ECMAScript

图片 51图片 52

因为javascript1.0的成功,netscape在navigator 3.0中发布1.1版。此时微软决定进军浏览器,在IE3.0种搭载了javascript的克隆版,叫JScript。在微软进来以后,有三种不同的javascript版本存在,即navigator3.0的javascript、IE的JScript、以及Cenvi中的ScriptEase。
由于javascript没有一个标准来统一其语法和特性,3种不同版本的恰恰突出了这个问题,这个语言的标准化显然势在必行。
1997年,javascript1.1作为一个草案提交给欧洲计算机制造协会(ECMA)。最后定义为ECMAScript的全新脚本语言。从此,浏览器开始努力将ECMAScript作为Javascript的基础。

Javascrip历史

八进制和十六进制介绍及转换

八进制:一种以8为基数的计数法。采用0,1,2,3,4,5,6,7八个数字,逢八进1。js以数字0开始表明该数字是八进制。

十六进制:计算机中数据的一种表示方法。它由0-9,A-F组成,字母不区分大小写。与10进制的对应关系是:0-9对应0-9;A-F对应10-15;js以0x开始表明该数字是十六进制。

js的进制转换,分为2进制,8进制,10进制,16进制之间的相互转换,我们直接利用对象.toString()即可实现:

 

如果要处理2进制到10进制,16进制到10进制,8进制到10进制, 需要用了paresInt这个方法:

 

进制转换:如果要实现进制之间的转换, 可以利用parseInt方法, 先转化为10进制, 然后再利用toString(参数), 转化成不同的进制。

// 进制的转换:二进制(0和1)、八进制、10进制、16进制
// var a = 011; // 8进制的转换
// var a = 0x1f;   // 16进制
// document.write(a);

// 转换公式:从右往左去数,3 * 8 ^ 0   2 * 8 ^ 1
// var a = 023;
// 转换公式:从右往左去数,14 * 16 ^ 0   3 * 16 ^ 1   10 * 16 ^ 2
// var a = 0xa3e;
// document.write(a); // 2622

// var a = 0456;

// document.write(parseInt(a, 10));

// document.write(a.toString(8));
// document.write(a.toString(16));

// document.write(a.toString(16));

 

上面代码的toString方法返回数值2(不是字符串),则最终结果就是数值3。

Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN。
参数为对象的转换规则:简单的规则是,Number方法的参数是对象时,将返回NaN。

十四、JavaScript语句

(一)选择语句

1)if语句

(1)单一选择结构:if(){}  

var x=5,y=8; if(y>x) { 
  alert("x>y");
}

(2)二路选择结构:if(){}else{} 

// 判断:如果第一个值大于第二个值则alert(OK!)
var x=5,y=8;
if(y> x){
   document.write('OK!');
}
else{
  document.write('NOT OK!');
}  

(3)三目运算符:?: (condition ? if_true : if_false;) 

var x=5,y=8; alert(x> y? 'OK!' : 'NOT OK!')

(4)多路选择结构:if(){}else if(){}else if(){}else{}

多路选择结构流程图:

图片 53

//此处给出主要代码为例
if(sScore >= 0 && sScore < 60) {
  alert('不及格,平常干啥啦!');
 } else if(sScore >= 60 && sScore < 70) {
  alert('刚刚及格,继续努力!');
 } else if(sScore >= 70 && sScore < 80) {
  alert('一般,再接再厉!');
 } else if(sScore >= 80 && sScore < 90) {
  alert('良好,稳住,你可以的!');
 } else if(sScore >= 90 && sScore < 100) {
  alert('优秀,戒骄戒躁,争取满分!');
 } else if(sScore == 100) {
  alert('劳逸结合,注意身体!');
 } else {
  alert('分数非法!');
 }

2)switch语句(考虑多路选择的案例转换为switch实现,提示:case后的是具体的情况,多路选择是以表达式的方式进行判断,即点和面的关系。如:80-90范围这个面通过除以10,然后通过parseInt进行取整。(面转成点))

语法:switch(condition){case :break;default:}

break具体讲解:阻止代码向下一个case运行。防止case穿透(穿透性用的好还是挺6的,有时间后续补充案例:给定依据具体日期得出这是本年的第多少天的案例)。

default具体讲解:匹配不存在时做的事情。

switch:严格检查类型(形似===的检查),如果不统一,条件不成立(比如说数字的字符串和case后的Number后的数字无法匹配,需转成相同的类型)

  // 判定
  switch(iWeekday){
    //利用穿透性
    case 0:
    case 7:
      alert('星期天');
      break;
    case 1:
      alert('星期一');
      break;
    case 2:
      alert('星期二');
      break;
    case 3:
      alert('星期三');
      break;
    case 4:
      alert('星期四');
      break;
    case 5:
      alert('星期五');
      break;
    case 6:
      alert('星期六');
      break;
    default:
      alert('非法数据!');
  }                         

  (二)循环语句

1)for循环语句

// for循环语法
/*
 for(var i = 0; i < 10; i  ){
  code...
 }
*/

for(var a = 4; a < 10; a  ) {
 document.write(a);
}

// for循环的嵌套
for(var i = 0; i < 5; i  ) {
 for(var j = 0; j < 5; j  ) {
  document.write(i*j   '、');
 }
 document.write('<br>');
}

 

图片 54图片 55

/*
    第1步:声明变量i = 0;
    第2步:判断条件i < 4,条件成立执行第三步,不成立则退出循环
    第3步:执行代码块。
    第4步:执行i  
    第5步:判断条件,i < 4,条件成立执行第6步,不成立则退出循环
    第6步:执行代码块。
    第7步:执行i  
    第8步:判断条件,i < 4,条件成立执行第9步,不成立则退出循环
*/
for(var i = 0; i < 4; i  ) {
    document.write(i);
}

for执行步骤

 

2)for in语句(可以遍历数组和对象,经常用于遍历对象)

遍历数组

var names = ["nick", "jenny"];

for(var index in names){
    console.log(index);
    console.log(names[index]);
}

遍历对象 

var obj = {name: '张三', age: 24, hobby: ['打篮球', '搏击', '打乒乓球']};
for(var attr in obj) {
    console.log(obj[attr]);
}

 3)while循环语句

/*
  while语法
while(condition){
  code...
}
*/
var a = 4;

while(a < 10) {
  document.write(a);
 a  ;
}

 4)do-while语句 

/*
do...while语法
do{
  code...
}while(condition);
*/
var a = 4;
do{
  document.write(a);
  a  ;
}
while(a < 10);
// while和do...while的区别:执行的顺序不一样
//do...while至少会执行一次代码块,while有可能一次都不执行。

  (三)Label语句 

 //label语句   跳出双重循环   例:条件 i=5 j=5 时  跳出嵌套的双重for循环   num=55;
 var num = 0;
        outPoint:
        for (var i=0;i<10;i  ) {
            for (var j=0;j<10;j  ) {
                if (i==5 && j==5) {
                    break outPoint;
                }
                num  ;
            }
        }
        console.log(num); //控制台输出

 (四)异常处理 

try {
    //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行
}
catch (e) {
    // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行。
    //e是一个局部变量,用来指向Error对象或者其他抛出的对象
}
finally {
     //无论上述代码怎么,finally代码块始终会执行
}

 补充:break和continue的区别 

// break和continue
for(var i = 0; i < 10; i  ) {
if(i === 5) {
break;
}
document.write(i);
}
for(var i = 0; i < 10; i  ) {
if(i === 5) {
continue;
}
document.write(i);
}
// 区别:break终止循环,continue跳过当前循环。
// 共同点:都不会执行后面的代码。

5:js注释

[] {}// "[object Object]"

Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN

四、文件引入

 <script>标签用于定义客户端脚本。它既可以包含脚本语句,也可以通过src属性指定外部脚本文件。

属性:

language:用来指定<script>标签中的脚本类型,即javascript。已废弃,大多数浏览器已经忽略它了,所以不要在使用。

type:它也是用来指定<script>标签中的脚本类型,即text/javascript。它也是type的默认值,所以可以忽略指定。

src:指定外部的脚本文件。如果指定该属性,script标签包含的JS脚本不会执行。

不可以使用单标签,即<script type=“text/javascript”/>。

1) 引入外部文件

<script type="text/javascript" src="JS文件"></script>

2.存放在HTML的<head>或<body>中

<script type="text/javascript">
    Js代码内容
</script>
  • HTML的head中
  • HTML的body代码块底部(推荐)

3) 为什么要放在<body>代码块底部?

  • HTML代码从上到下执行,先加载CSS,避免html出现无样式状态;
  • 将JavaScript代码块放在<body>最后,可以让网页尽快的呈现给用户,减少浏览者的等待时间,避免因为JS代码块阻塞网页的呈现。

数值:转换后还是原来的值。

 11、强制转换

十六、js的解析顺序

 第一步:加载第一个script代码块
 第二步:语法检查
 第三步:预解析(将var声明的变量和声明式创建的函数放到代码的最前面)
 第四步:开始正式执行代码,从上往下。
 第五步:加载第二个script代码块。

 

sum();
var sum = function () {
 console.log(a   8);
}
alert(a);   //undefined
alert(b);   //报错 
var a = 5;

//代码预解析时,先将a和sum变量放到代码最前方,然后创建代码  var a,sum;然后自上而下执行代码
//预编译的代码结构:
//var a,sum;
//sum();
//var sum = function () {
// console.log(a   8);
//}
//alert(a);   //undefined
//alert(b);   //报错 
//a = 5;

null

十七、对象

由若干个键值对组成的无序集合。每个属性存放一个原始值,对象或函数

属性:用属性值来描述他的状态

行为:用来改变队形的行为方法

1>对象申明

var obj = {
    name: 'jimmy',
    introduce: function () {
        console.log('我叫jimmy!');
    }
};
// 通过Object构造函数创建对象
// var obj = new Object();
// 通过自定义的构造函数创建对象
// function Animal() {}
// var dog = new Animal();
// console.log(dog);

2>对象的操作

创建对象:

 var bird = {feather: '羽毛', 'color': 'white', "type": '鸟类'};
 var dog = {};

<1>对象调用

console.log(bird.feather);
console.log(bird["feather"]);

<2>对象增加

方式1:通过.的方式

 dog.name = '旺财';
 dog.wagTails = function () {
   console.log('旺财正在摇尾巴!');
};

// dog.wagTails();//调用

方式2:通过[]的方式

dog["name"] = '大黄';
dog['tongues'] = function () {
  alert('大黄正在吐舌头!');
}
//dog.tongues();
//console.log(dog); 

 

<3>对象修改 

bird.feather = 'wing';
bird.color = 'pink'; 

<4>对象删除

delete bird.feather;

<5>对象清空

bird = {};

<6>对象销毁 

// JS的垃圾回收机制:JS引擎检测内存,如果某个对象没有被变量引用,那么就会直接回收该对象
var obj = {size: 100000000}; 
obj = null; 

十二、自动转换

自动转换具有不确定性,而且不易除错,建议在预期为布尔值、数值、字符串的地方,全部使用Boolean、Number和String函数进行显式转换。

自动转换的规则:预期什么类型的值,就调用该类型的转换函数。比如,某个位置预期为字符串,就调用String函数进行转换。如果该位置可能是字符串,也可能是数值,那么默认转为数值。

1:自动转换为布尔值:当JavaScript遇到预期为布尔值的地方(比如if语句的条件部分),就会将非布尔值的参数自动转换为布尔值。系统内部会自动调用Boolean函数。

if ( !undefined && !null && !0 && !NaN && !'' )

{ console.log('true'); } // true

// 写法一 expression ? true : false

// 写法二 !! expression

2:自动转换为字符串:当JavaScript遇到预期为字符串的地方,就会将非字符串的数据自动转为字符串。系统内部会自动调用String函数。字符串的自动转换,主要发生在加法运算时。当一个值为字符串,另一个值为非字符串,则后者转为字符串。( 号的拼接字符串的作用)

自动转换为字符串举例
'5' 1 // '51'  '5' true // "5true" '5' false // "5false"  '5' {} // "5[object Object]"
'5' [] // "5" '5' function (){} // "5function (){}" '5' undefined // "5undefined“ '5' null // "5null"

3:自动转换为数值:当JavaScript遇到预期为数值的地方,就会将参数值自动转换为数值。系统内部会自动调用Number函数。

自动转换为数值举例

'5' - '2' =3 

'5' * '2'=10

false - 1=-1

true - 1= 0

'5' * [] = 0

'1' - 1  = 0  

false / '5'    = 0

'abc' - 1 = NaN


4.除加法运算符有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值。

'abc' // NaN         -'abc' // NaN              true // 1             -false // 0

 特殊:(具体原因通过度娘寻根问底)

null == undefined   // true

null == false        // false

undefined == false // false

var str;
//undefined
console.log("只定义未初始化的str类型" typeof(str) "只定义未初始化的str值" str)
var strone="";
//string
console.log("初始化为""的str类型" typeof(strone) "初始化为""的str值" strone)
var strtwo=new String();
//无值相当于"";
if(""==strtwo)
console.log("初始化为new String()的str类型" typeof(strtwo) "初始化为new String()的str值" strtwo)
var strthree=null;
//object
console.log("初始化为null的str类型" typeof(strthree) "初始化为null的str值" strthree)  
var strfour={};
//object
console.log("初始化为{}的str类型" typeof(strfour) "初始化为{}的str值" strfour)

图片 56

1 {a:1}// "1[object Object]"

3>Boolean强制转换

一、定义:javascript是一种弱类型、动态类型、解释型的脚本语言。

弱类型:类型检查不严格,偏向于容忍隐式类型转换。

强类型:类型检查严格,偏向于不容忍隐式类型转换。

动态类型:运行的时候执行类型检查。

静态类型:编译的时候就知道每个变量的类型。

解释型:程序不需要编译,程序在运行的时候才翻译成机器语言,每执行一次都要翻译一次,因此效率比较低,但是跨平台性好。

编译型:程序在执行之前需要一个专门的翻译过程,把程序编译为机器语言的文件,运行时直接使用编译的结果就行了。

标记语言:标记语言的存在就是用来被读取(浏览)的,而其本身是没有行为能力的,在标记语言里你会看到<和>这些尖括号,这是用来写出“层次”和”属性”的,换句话说,它是被动的。并不具备与访问者互动的能力。

编程语言:它是具有逻辑性和行为能力,这是主动的。说通俗一点,它是有思想的。

脚本语言:它介于标记语言和编程语言之间,脚本语言不需要编译,可以直接用,由解释器来负责解释。

(4)空对象 空对象

十九、常用函数类型

1>回调函数(指针:通过函数名称的方式执行的函数) 

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。

因此,回调本质上是一种设计模式,并且jQuery(包括其他框架)的设计原则遵循了这个模式。

在JavaScript中,回调函数具体的定义为:函数A作为参数(函数引用)传递到另一个函数B中,并且这个函数B执行函数A。我们就说函数A叫做回调函数。如果没有名称(函数表达式),就叫做匿名回调函数。

因此callback 不一定用于异步,一般同步(阻塞)的场景下也经常用到回调,比如要求执行某些操作后执行回调函数。

例子
一个同步(阻塞)中使用回调的例子,目的是在func1代码执行完成后执行func2。

var func1=function(callback){
  //do something.
  (callback && typeof(callback) === "function") && callback();
}
func1(func2);
  var func2=function(){
}

function sum(a, b, fn) {
    var c = a   b;
    if(c > 9) {
        fn();
    }
    console.log(c);
} 
sum(7, 5, function () {
    alert(1);
});

回调函数的使用场合

资源加载:动态加载js文件后执行回调,加载iframe后执行回调,ajax操作回调,图片加载完成执行回调,AJAX等等。
DOM事件及Node.js事件基于回调机制(Node.js回调可能会出现多层回调嵌套的问题)。

setTimeout的延迟时间为0,这个hack经常被用到,settimeout调用的函数其实就是一个callback的体现

链式调用:链式调用的时候,在赋值器(setter)方法中(或者本身没有返回值的方法中)很容易实现链式调用,而取值器(getter)相对来说不好实现链式调用,因为你需要取值器返回你需要的数据而不是this指针,如果要实现链式方法,可以用回调函数来实现setTimeout、setInterval的函数调用得到其返回值。由于两个函数都是异步的,即:他们的调用时序和程序的主流程是相对独立的,所以没有办法在主体里面等待它们的返回值,它们被打开的时候程序也不会停下来等待,否则也就失去了setTimeout及setInterval的意义了,所以用return已经没有意义,只能使用callback。callback的意义在于将timer执行的结果通知给代理函数进行及时处理。

2>递归函数(自身调用自身的函数)

/*
递归函数调用分析:
    {
        var num = 1;
        num  ; // 2
        if(num < 5) {
            {
                var num = 2;
                num  ; // 3
                if(num < 5) {
                    {
                        var num = 3;
                        num  ; // 4
                        if(num < 5) {
                            {
                                var num = 4;
                                num  ; // 5
                                if(num < 5) {
                                    print(num);
                                }
                                console.log(num); // 5
                            }
                        }
                        console.log(num);
                    }
                }
                console.log(num);
            }
        }
        console.log(num);
    }
*/

function print(num) {
    num  ;
    if(num < 5) {
        print(num);
    }
    console.log(num);
}

print(1);

3>匿名函数

(function () {})();

4>构造函数

function Person() {
    alert(1);
}
var obj = new Person();
console.log(obj);

十七、对象

由若干个键值对组成的无序集合。每个属性存放一个原始值,对象或函数

属性:用属性值来描述他的状态

行为:用来改变队形的行为方法

1>对象申明

var obj = {
  name: 'jimmy',
  introduce: function () {
  console.log('我叫jimmy!');
  }
};

// 通过Object构造函数创建对象
// var obj = new Object();

// 通过自定义的构造函数创建对象
// function Animal() {}

// var dog = new Animal();

// console.log(dog);

 

2>对象的操作

创建对象:

 var bird = {feather: '羽毛', 'color': 'white', "type": '鸟类'};

 var dog = {};

<1>对象调用

console.log(bird.feather);
console.log(bird["feather"]);

<2>对象增加

 

方式1:通过.的方式
 dog.name = '旺财';
 dog.wagTails = function () {
   console.log('旺财正在摇尾巴!');
};

// dog.wagTails();//调用

方式2:通过[]的方式
dog["name"] = '大黄';
dog['tongues'] = function () {
  alert('大黄正在吐舌头!');
}
//dog.tongues();
//console.log(dog); 

<3>对象修改 

bird.feather = 'wing';
bird.color = 'pink'; 

<4>对象删除

delete bird.feather;

<5>对象清空

bird = {};

<6>对象销毁 

// JS的垃圾回收机制:JS引擎检测内存,如果某个对象没有被变量引用,那么就会直接回收该对象
var obj = {size: 100000000}; 

obj = null; 

对非数值类型的数据使用一元运算符(即“ ”和“-”)。

参数为原始类型值的转换规则:转换规则相对简单:除了以下六个值的转换结果为false,其他的值全部为true。
undefined、null、-0、0或 0、NaN、''(空字符串)
参数为对象的转换规则:所有对象(包括空对象)的转换结果都是true。

Number('tvr12.34n ')

十六、js的解析顺序

 第一步:加载第一个script代码块
 第二步:语法检查
 第三步:预解析(将var声明的变量和声明式创建的函数放到代码的最前面)
 第四步:开始正式执行代码,从上往下。
 第五步:加载第二个script代码块。

sum();
var sum = function () {
    console.log(a   8);
}
alert(a);   //undefined
alert(b);   //报错
var a = 5;

//代码预解析时,先将a和sum变量放到代码最前方,然后创建代码  var a,sum;然后自上而下执行代码
//预编译的代码结构:
//var a,sum;
//sum();
//var sum = function () {
//  console.log(a   8);
//}
//alert(a);   //undefined
//alert(b);   //报错
//a = 5;

所有对象的布尔值都是true,甚至连false对应的布尔对象也是true。

十二、自动转换

自动转换具有不确定性,而且不易除错,建议在预期为布尔值、数值、字符串的地方,全部使用Boolean、Number和String函数进行显式转换。

自动转换的规则:预期什么类型的值,就调用该类型的转换函数。比如,某个位置预期为字符串,就调用String函数进行转换。如果该位置可能是字符串,也可能是数值,那么默认转为数值。
   1:自动转换为布尔值:当JavaScript遇到预期为布尔值的地方(比如if语句的条件部分),就会将非布尔值的参数自动转换为布尔值。系统内部会自动调用Boolean函数。

if ( !undefined && !null && !0 && !NaN && !'' )

{ console.log('true'); } // true

// 写法一 expression ? true : false

// 写法二 !! expression

2:自动转换为字符串:当JavaScript遇到预期为字符串的地方,就会将非字符串的数据自动转为字符串。系统内部会自动调用String函数。字符串的自动转换,主要发生在加法运算时。当一个值为字符串,另一个值为非字符串,则后者转为字符串。( 号的拼接字符串的作用)

自动转换为字符串举例
'5' 1 // '51'  '5' true // "5true" '5' false // "5false"  '5' {} // "5[object Object]"
'5' [] // "5" '5' function (){} // "5function (){}" '5' undefined // "5undefined“ '5' null // "5null"

3:自动转换为数值:当JavaScript遇到预期为数值的地方,就会将参数值自动转换为数值。系统内部会自动调用Number函数。

自动转换为数值举例

'5' - '2' =3 

'5' * '2'=10

false - 1=-1

true - 1= 0

'5' * [] = 0

'1' - 1  = 0  

false / '5'    = 0

'abc' - 1 = NaN


4.除加法运算符有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值。

'abc' // NaN         -'abc' // NaN              true // 1             -false // 0

 特殊:(具体原因通过度娘寻根问底)

null == undefined   // true

null == false        // false

undefined == false // false

var str;
//undefined
console.log("只定义未初始化的str类型" typeof(str) "只定义未初始化的str值" str)
var strone="";
//string
console.log("初始化为""的str类型" typeof(strone) "初始化为""的str值" strone)
var strtwo=new String();
//无值相当于"";
if(""==strtwo)
console.log("初始化为new String()的str类型" typeof(strtwo) "初始化为new String()的str值" strtwo)
var strthree=null;
//object
console.log("初始化为null的str类型" typeof(strthree) "初始化为null的str值" strthree)    
var strfour={};
//object
console.log("初始化为{}的str类型" typeof(strfour) "初始化为{}的str值" strfour)

图片 57

字符串:转换后还是原来的值。

十五、函数

函数的概念:函数就是把完成特定功能的一段代码抽象出来,使之成为程序中的一个独立实体,起个名字(函数名)。可以在同一个程序或其他程序中多次重复使用(通过函数名调用)。
注:编写好的函数代码只有通过调用才会执行,不调用的时候不会执行(自执行函数特例)。
函数的作用(好处):
1,使程序变得更简短而清晰
2,有利于程序维护
3,可以提高程序开发的效率 ,
4,提高了代码的重用性(复用性)

1>函数的创建方式

// 函数声明式的方式创建函数
  function funcName() {}

// 函数表达式的方式创建函数
  var funcName = function () {};

// 通过构造函数的方式创建函数
// 构造函数:出现在new运算符后的函数,称为构造函数
  var funcName = new Function ();

函数声明式和函数表达式的区别

// 函数声明式的方式必须指定函数名
function sum() {
    alert(1);
}
sum();
// 函数表达式的方式可以没有名字
 (function () {
    alert(1);
 })();

2>函数的调用方式

//创建函数
function hello() {
   document.write('hello ');
   document.write('world ');
 }
// 方式1:手动调用
 hello();
// 方式2:事件驱动的方式
 var oBox = document.getElementById('box');
oBox.onclick = function () {
   hello();
 };

3>函数的参数(形参和实参)

1.手动传递的形参和实参

//函数定义时,定义的变量为形参:a,b
function sum(a, b) {
    alert(a   b);
}//函数调用时,传递的参数值为实参:4,8
sum(4, 8);

补充:对象中,冒号前面的数据可以称为键、下标、或者key,冒号后面的值称为值或者value

2.JS解析器内置定义的arguments (在函数内部的内置的对象参数,无需自定义可直接使用)

 arguments 值类型(对象类型),包含的是实参的个数和数据

function sum(a, b) {
    // 通过下标的方式获取某一个值
    console.log(arguments[0]);
    // 通过遍历的方式获取所有的值(下标0起始)
    for(var i = 0; i < arguments.length; i  ) {
        console.log(arguments[i]); //分别控制台打印5,3,8
    }
    a  ; //a和arguments[0]和指向相同结果可想而知,相同为6
    console.log(arguments[0]); //6 
    console.log(a); //6 
} 
//手动调用函数 
sum(5, 3, 8);

3.return(返回函数执行的结果) 

// return关键词
function sum(a, b) {
    var c = a   b;
    return c;/*!return只能返回参数只能有一个。return a,b,c 最终返回的结果是c的结果,不会报错*/
    /*!return 后面的代码不会执行*/
    alert('hello world!');//永远不会被执行
    // 函数默认返回的值是undefined
}
var d = sum(4, 7);
console.log(d);

Number函数:强制转换成数值

如果toString方法和valueOf方法,返回的都不是原始类型的值,则String方法报错。

undefined

null

({}) {}// "[object Object][object Object]"({} {})// "[object Object][object Object]"console.log({} {})// "[object Object][object Object]"vara={} {};a// "[object Object][object Object]"

(1)原始类型值的转换规则

布尔值:true转成1,false转成0。

自动转换为数值

除了加法运算符有可能把运算子转为字符串,其他运算符都会把两侧的运算子自动转成数值。

对象{a:1}的valueOf方法,返回的就是这个对象的本身,因此接着对它调用toString方法。({a:1}).toString()默认返回字符串"[object Object]",所以最终结果就是字符串“1[object Object]”

undefined:转为“undefined”。

两个运算子之中,只要有一个是字符串,则另一个不管是什么类型,都会被自动转为字符串,然后执行字符串连接运算。前面的《自动转换为字符串》一节,已经举了很多例子。

parseInt('011')// 9parseInt('42 cats')// 42parseInt('0xcafebabe')// 3405691582Number('011')// 11Number('42 cats')// NaNNumber('0xcafebabe')// 3405691582

字符串:如果可以被解析为数值,则转换为相应的数值,否则得到NaN。空字符串转为0。

版权声明:本文由ca888发布于ca888圈内,转载请注明出处:从零开端学习前端JAVASCLANDIPT — 壹、JavaScript基础