再学JavaScript (一)

144 阅读7分钟

资深伸手党尝试贡献自己的一份力量,

文章会结合知识点、示例及练习题进行学习,因为篇幅较长所以分为五部分来分享,基本涵盖了JavaScript(es3+es5)大部分知识点,有哪些不足和错误欢迎大家指正。

1. 浏览器知识拓展

1. 主流浏览器都有哪些?内核分别是什么?

主流浏览器内核
ChromeWebkit/Blink(2014)
FirefoxGecko
IETrident
SafariWebkit
OperaPresto

2. 浏览器的组成部分

shell部分

内核部分

  1. 渲染引擎(语法规则和渲染)
  2. Javascript 引擎
  3. 其他模块

2. 引入方式

1. 内联脚本

基本语法

<script>
	...
</script>

2. 外链脚本

基本语法

<script src="./js/main.js">

3. 内嵌脚本

基本语法

<div onclick=function() {console.log('内嵌脚本')}></div>

4.Web标准

W3C标准:结构、样式、行为相分离,通常都会采用外链的方式

3. varible 变量

1. 变量声明

声明、赋值步骤分解
var a;     // 变量声明
a = 1000;  // 变量赋值
单一var模式
var a,
    b,
    c = 300,
    d = 400,
    e = 500;

// 一个变量同时只能存储一个值
// 运算的顺序 = 右面的内容计算完再进行复制
命名规则
  1. 变量名必须以 英文字母 、_ 、$ 开头
  2. 变量名可以包括 英文字母、_ 、$、数字
  3. 不可以使用系统的 关键字、保留字 作为变量名

4. DataType 数据类型

原始值&引用值
数据类型 语法 描述 区别
原始值 Number 数值类型
  1. 原始值存储于栈(stack)内存- 先进后出(first in last out)- 不可改变的原始值
  2. 原始值与原始值相互赋值是拷贝
String 字符串类型
Boolean 布尔类型
undefined undefined类型
Null 空指针类型
引用值 Object 对象类型
  1. 引用值大部分存储于堆(heap)内存,栈内存内存储的是引用地址-先进先出
  2. 引用值赋值是指定引用
基本编写规则
  1. 语句后面要用分号结束
  2. js语法错误会引发后续代码终止,但不会影响其他 js 代码块
  3. 书写格式要规范, “ = + / - ” 两边都应该有空格

5. 操作符

1. 运算操作符

1.1“+” 运算符的两个功能

数学运算,字符串连接,任何数据类型与字符串相加都等于字符串

1.2 “ - ”,“ * ”,“ / ”,“ % ”,“ = ”,“ () ”

与数学运算相同, “ () ” 优先级最高,“ = ” 优先级最低

1.3 “++”、“--”、“+=”、“-=”、“/=”、“*=”、“%=”
1.4. 注意

赋值顺序 自右向左, 计算顺序 自左向右


2. 比较运算符

“>”、“<”、“==”、“>=”、“<=”、“!=”

与数学中的定义相同,比较的结果为 boolean 类型的值 true或false,字符串比较的是 ascii 码


3. 逻辑运算符

1.“&&”、“||”、“!”: 与或非

“&&”
var a = 1 && 2 + 2;
console.log(a); //4
// 如果表达式都为true,则返回最后一个表达式的计算结果,如果有false则直接返回当前为false的表达式,后面再有表达式也不再会向后计算

// 应用-中断作用
data && console.log('数据获取成功!');       //短路语句
data && fn(data);
“||”
var num = 0 || false || 1;
// 返回为true的表达式,如果都为false则返回最后一个为false的表达式

// 应用 + 点击事件判断
div.onclick = function(e) {
  // 获取事件源对象(e)中, IE浏览器和非IE浏览器是不同的, 一般用于做浏览器的兼容
  var event = e || window.event; // window.event IE 浏览器存储事件源对象的关键字
}
“!”
// 将表达式转换为布尔值再取反
var a = !123; // false
var b = !""; // true
var b = !!""; // false

2. 在系统中被默认为 false 的值

  1. undefined
  2. null
  3. NaN
  4. "" || " "(空串或者空的串)
  5. 0

6. 条件语句

1. if

语法

if(条件) { // 如何条件为 true 则执行代码体1
  // 代码体1
} else { // 如何条件为 false 则执行代码体2
  // 代码体2
}

2. if else

语法

if(条件1) {
  // 代码体1
} else if(条件2) {
  // 代码体2
} else {
  // 代码体3
}
// 使用 if else 做条件互斥,满足某一个条件则不会再往下进行判断

3. for

语法

for(var i = 0; i < 10; i ++) {
  console.log('a');
}
/*
for循环的执行顺序拆解
	1. var i= 0;
  2. if(i < 10) {
	console.log("a");
  }
  3. i++;
  4. if(i < 10) {
  console.log("a");
  }
 */
// for循环拆解写法
var a = 0;
for(; a < 10;) { // 空缺的位置直接忽略
  console.log('a');
  i ++;
}

4. while

语法

var i = 0;
while(i < 10) { // 满足条件就执行
  document.write(i);
  i ++;
}

5. do-while

语法

var i = 0;
do {
  document.write(i);
  i ++;
}while(i < 10)

6. switch case

语法

switch(number) {
  case 1:
    console.log('a');
    break; // 需要配合break; 来终止语句停止后面的判断和输出
  case 2:
    console.log('b');
  default:
    console.log('default');
}

7. break continue

  • break: 结束当前判断 / 循环
  • continue: 跳过本次判断 / 循环

编码练习

1. 计算 2 的 n 次幂, n 可输入, n 为自然数

/*  规律
    1 * 2
    1 * 2 * 2
    1 * 2 * 2 * 2
    1 * 2 * 2 * 2 * 2
  */ 

// 实现
var n = parseInt(window.prompt('input'));
var mul = 1;
for(var i = 0; i < n; i ++) {
  mul *= 2;
}
document.write(mul);

2. 计算 n 的阶乘, n 可输入

/* 规律
	5!:5 * 4 * 3 * 2 * 1 * 1
  4!:4 * 3 * 2 * 1 * 1
*/ 

// 实现
var n = parseInt(window.prompt('计算n的阶乘'));
var mul = 1;
for(var i = 1; i <= n; i ++) {
  mul *= i;
}
console.log(mul);

3. 斐波那契数列第n位,n 可输入

/* 规律
    1 1 2 5 8
 */

// 实现
var n = parseInt(window.prompt("斐波那契"))
var num1 = 1;
var num2 = 1;
var num3 = 0;
if(n > 2) {
  for(var i = 0; i < n - 2; i ++) {
    num3 = num1 + num2;
    num1 = num2;
    num2 = num3;
  }
  console.log(num3);
} else {
  console.log(1);
}

4. 编写一个程序,输入三位数, 然后将其反向输出

var num = parseInt(window.prompt("三位数"));
var sum = 0;
var num1 = num % 10;
var num2 = (num - num1 % 100) / 10 % 10;
var num3 = (num - (num2 * 10 + num1) )/ 100;
console.log(num1, num2, num3);
sum = (num1 * 100) + (num2 * 10 ) + num3;
console.log(sum);

5. 输入三个数字,打印最大的

var numA = parseInt(window.prompt("数字A"));
var numB = parseInt(window.prompt("数字B"));
var numC = parseInt(window.prompt("数字C"));
if(numA > numB) {
  if(numA > numC) {
    console.log(numA);
  }else {
    console.log(numC);
  }
} else {
  if(numB > numC) {
    console.log(numB);
  } else {
    console.log(numC);
  }
}

6. 打印100以内的质数

var count = 0;
for(var i = 1; i < 100; i ++) {
  for(var j = 1; j <= i; j ++) {
    if(i % j == 0) {
      count ++;
    }
  }
  if(count == 2) {
    console.log(i);
  }
  count = 0;
}

7. typeof 六种数据类型

  1. number
  2. string
  3. boolean
  4. object : 数组、对象和null都会返回object (null 最初是对象占位符,代替空对象,属于历史遗留问题)
  5. undefined: 变量声明却没有初始化时,undefined会作为变量的默认值。
  6. functtion

注意

typeof() 在ES5及以下版本中访问没有定义的变量是不会报错的


8. 类型转换

1. 显式类型转换

Number(param)

将参数转换为数值类型并返回。


示例
  • null : 0
  • undefined: NaN (NaN: Not a Number(不是一个数))
  • 123abc : NaN
  • true : 1

parseInt(param)

将参数转换为整数 intiger

示例
  • true : NaN
  • 1.9 : 1
  • 123abc: 123 (如果以数字位开头则会自动截断后面的非数字位,将数字位返回)
  • 100px : 100
  • parseInt(param, radix): radix: 表示基底,例如:parseInt(num, 16); 以十六进制将num转换为十进制
  • parseInt(30, 16): 1e

parseFloat(param)

将参数转换为浮点型


示例
  • 100 : 100
  • 100.1 : 100.1
  • 100.1.1 : 100.1
  • 100.1abc : 100.1

String(param)

将参数转换为字符串


Boolean(param)

将参数转换为布尔类型,可以参考上面章节中逻辑运算符>在系统中被认为 false 的值


toString()

是用 “.” 的方式调用当前方法,将调用此方法的属性转换为字符串

示例
  • sex.toString(): "18" (不要问,问就是永远18岁)
  • 不可以调用toString()方法的类型
    1. undefined
    2. null

.toString(radix): 将十进制的值转换为目标进制(radix)


2. 隐式类型转换

isNaN(param)

判断是不是一个数

示例
isNaN('abc') -隐式调用-> Number('abc') =然后和NaN进行比较= NaN?  true:false;

++、--、+、- (一元正负)

自动隐式调用Number(),强制转换成Number类型

示例
//自动隐式调用Number(),强制转换成Number类型
var a = "123";
a++;
// a = 124
var b = "abc";
b++;
// b = NaN

+ -、*、/、%

  1. 当加号两边有一个是字符串的,则将两边都转换为字符串并连接,如果是数值就做加法运算
  2. 如果是数值类型会隐式调用Number()方法

&&、||、!

“!” 调用 Boolean() 进行转换


>、<、<=、>=

  • var a = "3" > 2 : ture; 有数字时会隐式调用 Number() 进行转换再比较
  • var a = "b" > "c": false 如果比较运算符两侧都是字符串,则比较的是对应的ascii码

==、!=

同样有隐式类型转换


9.函数

1. 定义方式


1. 函数声明

function fn() {
  // ...
}

2. 函数表达式


1. 命名函数表达式
var fn = function test() {
  // test 不代表函数体,在函数中 fn.name == test
  console.log(fn.name); // test
}
2. 匿名函数表达式(常用方式)
var fn = function() {
  
}

2. 组成形式

  1. 函数名称

    1. 命名规则与变量一致
    2. 多个单词使用小驼峰命名法 theIsFnName
  2. 参数

    1. 形参

      // 传递形式参数(形参)
      function functionName(a, b) {
          // 在括号中传递a, b就相当于隐式的在函数中  var a; var b;
      }
      
    2. 实参

        // 传递实际参数(实参)
        functionName(1, 2);
      
  3. arguments

    一个类数组,保存传进的实参

    function functionName(a, b, c, d) {
        console.log(arguments);   // 打印实参列表 Arguments(3) [1, 2, 4]
        console.log(functionName.length);  //  5 计算形参的长度
        // 如果形参比实参多,那么多余的形参将默认是undefined,未赋值
    }
    functionName(1, 2, 4)
    
      // 不再存在映射关系案例
      function test(a, b) {
        arguments[1] = 2;
        console.log(b); // undefined
        // 或者
        b = 2;
        console.log(arguments[1]); // undefined
      }
      test(1);
    
  4. return

    终止当前函数,return之后的语句将不会得到执行

    可以在该关键字之后设置返回值


10. 递归

类似于循环,使一个处理函数根据需求执行多次

关键点

  1. 找规律
  2. 找出口

示例

 // 1. 找规律    
  // 2. 找出口
  
  // 使用递归实现阶乘
  function mul(n) {
      if(n == 1 || n == 0) {  // 用已知的作为递归的出口
          return 1;
      }
      return n * mul(n - 1); // 使用公式作为递归的逻辑
  }
  console.log(mul(5))
  
  // 使用递归实现斐波那契数列 
  function fb(n) {
      if(n == 1 || n == 2) { // 用已知的作为递归的出口
          return 1;
      }
      return fb(n-1) + fb(n-2); // 使用公式作为递归的逻辑
  }
  fb(10);