ECMAScript5-P1(基础部分:数据类型+流程控制……)

本文详细介绍了JavaScript的基础知识,包括其语言特点、运行环境、变量、数据类型(如字符串、数字、布尔型、null、undefined、symbol、对象、数组和函数)、类型判断、操作符、类型转换以及流程控制结构(如if-else、switch和循环语句)。JavaScript是一门解释型、弱类型的脚本语言,常用于前端开发,与DOM和BOM交互。文章还探讨了变量声明提前、数据类型在内存中的存储以及不同类型间的转换策略。
摘要由CSDN通过智能技术生成
提示:以下代码均是在node环境下运行


什么是Javascript

在前端三大剑客中,js是最重要的一门语言,是一门轻量级脚本语言,使用户能够与网页、浏览器进行交互。

js组成部分

  1. ECMAScript(js标准、制定了基础语法)
  2. DOM(文档对象模型,与网页进行交互)
  3. BOM(浏览器对象模型,与浏览器进行交互)

js运行环境

  1. 含有js解析器的浏览器中
  2. node.js环境中

js语言特点

  1. 解释型语言
  2. 弱类型语言
  3. js代码从上至下顺序执行
  4. 区分大小写

使用方式

  1. 写在head标签中,引用外部js文件
  2. 写在body所有html代码后面,使用script标签
    区别:
    ①代码是从上至下顺序执行的,当执行到head标签中的js文件时,此时html结构并未执行完,js中的值会返回空值;
    ②在body后面执行js代码:这时已经执行完html结构,js中的值不会为空;
    解决办法:
    在js外部文件中:在所有js代码外边添加监听,表示当页面加载完之后再执行js代码
windows.onload = function(){
	// 这里放执行的代码
}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <!-- 原生项目的开发模式 -->
  <!-- 引入css -->
  <!-- 引入js -->
  <script src="./01-main.js"></script>
  <!-- head标签内 编写或引入js代码 -->
  <script>
    // 编写js代码
      console.log(this);
  </script>
</head>
<body>
  <div></div>
  <!-- body标签内 编写或引入js代码 -->
  <script>
    // 编写js代码
    alert('Hello JS2')
  </script>
</body>
</html>

js注释

  1. //
  2. /* */

标识符规范

  1. 以字母、数字、下划线和美元符号$组成
  2. 不能以数字开头

变量

声明变量

使用var关键字声明变量,变量的类型在赋值结束时决定,可以进行多次声明赋值

//使用var声明变量并赋值
//声明变量的名称
var a;
//给变量赋值 变量的数据类型与赋值的类型决定
a = 3;
console.log(a);//3

var声明提前

console.log(a);//undefined
var a = 123
console.log(a);//123

代码实际如下:即为变量声明提前

var a; //声明提前
console.log(a);//undefined
a = 123
console.log(a);//123

数据类型

基本数据类型(简单数据类型)

String(字符串)

通过单引号或者双引号包裹的字符即为字符串
字符串的字符长度可以通过属性length获取

var str1 = '123'
var str2 = "hello"

Number(数字)

var num1 = 12
var num2 = 23.45
var num2 = 010;//8
var num3 = 0x10;//16

Boolean(布尔型)

只有两种值:true、false

var real = true
var fake = false

null

var a = null

undefined

声明但未赋值,值就是undefined

var a

symbol

var s = Symbol('我是独一无二的symbol')

引用数据类型(复杂数据类型)

Object(对象)

,用来保存多个数据的容器,由大括号包裹键值对组成

var obj = {
	name:'spylent',
	age:20
}

Array(数组)

数组是一个特殊的对象,包含了多个值,值与值之间使用逗号分隔开,所有的值通过中括号括起来。
值可以是任意类型

var arr =[1,2,'string',[12,2],true]

Function(函数)

函数中包含多条代码,通过()执行函数实现功能

function fun(){
	console.log("我是一个函数")
}
fun()

基本数据类型与引用数据类型在内存的存储

在这里插入图片描述

undefined和null的关系

  1. undefined派生于null
console.log(undefined == null)//true
// ==:等同的意思, 两边值类型不同的时候,要先进行类型转换为同一类型后,再比较值是否相等。
  1. undefined指声明但未赋值
  2. null指声明且赋值为null,表示空对象

类型判断

typeof

使用typeof判断数据类型:返回值是字符串
typeof能够准确判断 string、number、boolean、undefined、symbol、function
不能准确判断 null和Object、array和Object

typeof 123 //'number'
typeof 'str' //'string'
typeof true//'boolean'
typeof Symbol() //'symbol'
var a
typeof a//'undefined'
var fun = function(){}
typeof fun //'function'
typeof null //Object
typeof [] //Object

不能准确判断原因:
因为javascript历史遗留问题,js中判断类型是以二进制前三位数以此判断是什么类型,null、array的前三位二进制数与Object前三位二进制数都一致,所以不能准确判断;

isNaN

判断是否不是一个数字

var b = 10/'a'
console.log(isNaN(b))//true 不是一个数字

isFinite

判断是否是一个有效值
由于内存的限制,ECMAScript不能保存世界上所有的数值。果某次计算的结果超过了JavaScript数值范围,将会返回Infinity(正无穷)或者-Infinity(负无穷);

var a = 9/0;   // Infinity
Number.MIN_VALUE    5e-324
Number.MAX_VALUE   1.7976931348623157e+308

操作符

算数运算符

进行数据运算时,除'+'外,其他运算符可以自动将字符串数字隐形转成数字
var num1 = 2
var num2 = 8
console.log(num1 + num2)//10
console.log(num1 - num2)//-6
console.log(num1 * num2)//16
console.log(num1 / num2)//0.25
console.log(num1 % num2)//2

var num3 = '6'
var num4 = '2'
console.log(num3 + num4)//62
console.log(num3 - num4)//4
console.log(num3 * num4)//12
console.log(num3 / num4)//3
console.log(num3 % num4)//0

一元运算符

在这里插入图片描述

//可以将数字字符串或布尔类型等隐式转换成number类型
console.log(+'89', typeof +'89')//89 number
//与字符串运算时,就是字符串连接符
console.log('a' + 2, typeof 'a' + 2)//a2 string2
//正、负号可以将字符串数字隐式转换成数字
console.log(-'100', typeof -'100')//-100 number


if (!a) {
  var a = 10
  //++放在后面,并进行赋值:先赋值,后累加
  let num = a++
  console.log("num = " + num + ", a = " + a)//num = 10, a = 11
  //++放在前面,并进行赋值:先累加,后赋值
  num = ++a
  console.log("num = " + num + ", a = " + a)//num = 12, a = 12
  //--放在后面,并进行赋值:先赋值,后累减
  let sub = a--
  console.log("num = " + sub + ", a = " + a)//num = 12, a = 11
  //--放在前面,并进行赋值:先累减,后赋值
  sub = --a
  console.log("num = " + sub + ", a = " + a)//num = 10, a = 10
}


var obj = {
  name: '张三',
  age: 18
}
console.log(obj)//{ name: '张三', age: 18 }
//删除数组或对象中特定索引的值
delete obj.age
console.log(obj)//{ name: '张三' }


var arr = [1, 3, 4, 52, "a"]
console.log(arr)//[ 1, 3, 4, 52, 'a' ]
delete arr[3]
console.log(arr, arr.length, arr[3])//[ 1, 3, 4, <1 empty item>, 'a' ] 5 undefined


var b = 333
console.log(void b)//undefined

赋值运算符

var a = 5;
var num1 = 5;
var num2 = 6;
console.log(num1 += num2, num1, num2);//11 11 6
console.log(num1 -= num2, num1, num2);//5 5 6
console.log(num1 *= num2, num1, num2);//30 30 6
console.log(num1 /= num2, num1, num2);//5 5 6
console.log(num1 %= num2, num1, num2);//5 5 6

比较运算符

var b = '5'
//两边值类型不同的时候,要先进行类型转换为同一类型后,再比较值是否相等
console.log(a == b)//true
//不做类型转换,类型不同的结果一定不等
console.log(a === b)//false
console.log(a != b)//false
console.log(a !== b)//true
console.log(a > b)//false
var c = 'a3'
console.log('b' > c)//true
console.log('12345' > '11456');//unicode比较  true
console.log('12345' > +'11456');//数值比较   true


var obj = { a: 1 }
var obj1 = obj
console.log(obj1 == obj)//true
console.log(obj1 === obj)//true
console.log(obj == '[object Object]')//true
console.log(obj === '[object Object]')//false

相等和全等的注意点

  1. 对于基本数据类型:双等和全等是有区别的
  2. 对于引用数据类型:双等和全等是没有区别的,只进行“指针地址”比较
  3. 当引用数据类型和基本数据类型使用相等时,引用数据类型先转换为基本数据类型,再进行值的比较

逻辑运算符

//同真才真,有假则假
console.log(123 && 345)//345
console.log(undefined && 123)//undefined
console.log('' && 8)//''
console.log(123 && false)//false


//有真才真,同假则假
console.log(123 || 345)//123
console.log(undefined || 123)//123
console.log('' || 8)//8
console.log(123 || false)//123
console.log("" || 0)//0


var a
console.log(!a)//true
console.log(!0)//true
console.log(!'')//true
console.log(!1)//false

三目运算符

//基本语法为: expression ? sentence1 : sentence2
//当expression的值为真时执行sentence1,否则执行 sentence2
var a;
1 > 2 ? a = 3 : a = 5
console.log(a)//5

类型转换

其他基本数据类型转字符串

注:除了null,undefined,其他三种基本数据类型的变量均有一个toString()函数
var a = true;
var b = 123;
var c = Symbol('123')
console.log(a.toString(), b.toString(), c.toString());
//true 123 Symbol(123)
console.log(typeof a.toString(), typeof b.toString(), typeof c.toString());
//string string string


// var d;
// var e = null
// console.log(d.toString()) //Cannot read property 'toString' of undefined
// console.log(e.toString()) //Cannot read property 'toString' of null

console.log("**********进制")
var num = 10;
console.log(num.toString());//10
console.log(num.toString(2))//1010
console.log(num.toString(8))//12
console.log(num.toString(16))//a

其他基本数据类型转数字

Number()

console.log(Number(true))//1
console.log(Number(false))//0
console.log(Number(null))//0
console.log(Number(undefined))//NaN
console.log(Number(10))//10


console.log(Number("+12.1"))//12.1
console.log(Number("1+2.3"))//NaN
console.log(Number("0xa"))//10
console.log(Number("010"))//10
console.log(Number("123ac"))//NaN

parseInt()函数

如果转换的值是null,undefined,boolean,均转换为NaN
console.log(parseInt("+12.1"))//12
console.log(parseInt("1+2.3"))//1
console.log(parseInt("0xa"))//10
console.log(parseInt("010"))//10
console.log(parseInt(''))//NaN
console.log(parseInt("123ac"))//123

parseFloat()函数

如果转换的值是null,undefined,boolean,均转换为NaN
console.log(parseFloat("+12.1"))//12.1
console.log(parseFloat("1+2.3"))//1
console.log(parseFloat("0xa"))//0
console.log(parseFloat("010"))//10
console.log(parseFloat(''))//NaN
console.log(parseFloat("123.3ac"))//123.3

其他基本数据类型转布尔

转换任意其他数据类型都可以转换为布尔类型

Boolean()

console.log(Boolean('hello'))//true
console.log(Boolean(0))//false
console.log(Boolean(null))//false
console.log(Boolean(undefined))//false
console.log(Boolean({ name: 'cym' }))//true
console.log(Boolean(Symbol('123')))//true
console.log(Boolean([]))//true
var fun = function () { }
console.log(Boolean(fun))//true

!!

console.log(!!undefined)//false
console.log(!!null)//false
console.log(!!'')//false
console.log(!!123)//true
console.log(!!Symbol())//true
console.log(!!{})//true
console.log(!![1, 2, 3])//true
var fun1 = function () { console.log("aa") }
console.log(!!fun1)//true

基本数据类型隐式转换

1.字符串加数字,数字就会转成字符串。数字加数字或字符串加字符串不需要转换。

在加法的过程中,首先把等号左右两边进行了求原值ToPrimitive()操作,如果有两个或多个原始值,只要其中有一个是String类型,就把两个或多个原始值都进行转化字符串toString()操作,进行字符串拼接;否则把两个或多个原始值都进行转化数字toNumber()操作,进行数字相加。

2.数字减字符串,字符串转成数字。如果字符串不是纯数字就会转成NaN。字符串减数字也一样。两个字符串相减也先转成数字。

3.乘,除,大于,小于跟减的转换也是一样。

var a = 1 + 2 + '3'
var b = 2 + '100a'
var c = 3 + 'a'
console.log("a = " + a, typeof a)//a = 33 string
console.log("b = " + b, typeof b)//b = 2100a string
console.log("c = " + c, typeof c)//c = 3a string


var d = 10 - '100'
var e = 2 - 'a'
var f = 3 - '100a'
console.log("d = " + d, typeof d)//d = -90 number
console.log("e = " + e, typeof e)//e = NaN number
console.log("f = " + f, typeof f)//f = NaN number


var g = 10 / '100'
var h = 8 / 'a'
var i = 3 % '100a'
console.log("g = " + g, typeof g)//g = 0.1 number
console.log("h = " + h, typeof h)//h = NaN number
console.log("i = " + i, typeof i)//i = NaN number


console.log("1=='1':", 1 == '1')//1=='1': true
console.log("undefined==null:", undefined == null)//undefined==null: true
console.log("0==false:", 0 == false)//0==false: true
console.log("'0'==false:", '0' == false)//'0'==false: true
console.log("''==false:", '' == false)//''==false: true

引用数据类型隐式转换

  • 通过ToPrimitive将值转换为原始值

    原始值:字符串、数字

js引擎内部的抽象操作ToPrimitive有着这样的签名:

ToPrimitive(input, PreferredType?)

input是输入的值,即要转换的对象,必选;

preferedType是期望转换的基本类型,他可以是字符串,也可以是数字。选填,默认为number;

他只是一个转换标志,转化后的结果并不一定是这个参数值的类型,但是转换结果一定是一个原始值(或者报错)。

对于Date求原始值比较特殊,PreferredType是String,其他Object对象均为Number。

既然要隐式转换,就应该有一套转换规则,才能追踪最终转换成了什么

隐式转换中主要涉及到三种转换:

1、将值转为原始值,ToPrimitive()。

2、将值转为数字,ToNumber()。

3、将值转为字符串,ToString()。

PreferredType转换策略:每一个步骤都要依赖上一个步骤的结果
  • 如果PreferredType被标记为Number,则会进行下面的操作流程来转换输入的值。

1、如果输入的值已经是一个原始值,则直接返回它
2、否则,如果输入的值是一个对象,则调用该对象的valueOf()方法,
如果valueOf()方法的返回值是一个原始值,则返回这个原始值。
3、否则,调用这个对象的toString()方法,如果toString()方法返回的是一个原始值,则返回这个原始值。
4、否则,抛出TypeError异常。

  • 如果PreferredType被标记为String,则会进行下面的操作流程来转换输入的值。

1、如果输入的值已经是一个原始值,则直接返回它
2、否则,调用这个对象的toString()方法,如果toString()方法返回的是一个原始值,则返回这个原始值。
3、否则,如果输入的值是一个对象,则调用该对象的valueOf()方法,
如果valueOf()方法的返回值是一个原始值,则返回这个原始值。
4、否则,抛出TypeError异常。

注意:

​ PreferredType的值会按照这样的规则来自动设置:

​ 1、该对象为Date类型,则PreferredType被设置为String

​ 2、否则,PreferredType被设置为Number

特殊情况1:
[] + [] // ""

进行ToPrimitive,两个都是Array对象,不是Date对象,所以以Number为转换标准,所以先调用valueOf(),结果还是[ ],不是原始值,所以继续调用toString(),结果是“”(空字符串)原始值,将“”返回。第二个[ ]过程是相同的,返回“”。加号两边结果都是String类型,所以进行字符串拼接,结果是“”。

特殊情况2:
[] + {}	// "[object Object]"

进行ToPrimitive,依然是以Number为转换标准。
[ ]的结果是“”。
{ }先调用valueOf(),结果是{ },不是原始值,所以继续调用toString(),结果是“[object Object]”,是原始值,将“[object Object]”返回。
加号两边结果都是String类型,所以进行字符串拼接,结果是“[object Object]”。

特殊情况3:
{} + [] // 0

这道题按照上一题的步骤,讲道理的话,结果应该还是“[object Object]”,但结果却出人意料——显示的答案是0!
这是什么原因呢?js解释器会将开头的 {} 看作一个代码块,而不是一个js对象;原来{ } + [ ]被解析成了{ };+[ ],前面是一个空代码块被略过,剩下+[ ]就成了一元运算。[ ]的原值是””, 将””转化成Number结果是0

特殊情况4:
{} + {} // "[object Object][object Object]"

在金丝雀版本的chrome浏览器和node中,结果符合预期。
结果是”object Object”。
在普通版本的chrome浏览器中结果是NaN。
这是为什么呢?原因是在node中会将以“{”开始,“}”结束的语句外面包裹一层( ),就变成了({ } + { }),结果就符合预期。而普通版本的chrome依然会解析成{};+{},结果就变成了NaN

console.log({}.valueOf(), typeof {}.valueOf());//{} object
console.log({}.toString(), typeof {}.toString());//'[object Object]' string

console.log([].valueOf(), typeof [].valueOf());//[] object
console.log([].toString(), typeof [].toString());//'' string

var a = {} + {}
var b = [] + []
var c = [] + {}
console.log(a, typeof a)//[object Object][object Object] string
console.log(b, typeof b)// string
console.log(c, typeof c)//[object Object] string

流程控制

if-else

  • if 语句 - 只有当指定条件为 true 时,使用该语句来执行代码
  • if…else 语句 - 当条件为 true 时执行代码,当条件为 false 时执行其他代码
  • if…else if…else 语句- 使用该语句来选择多个代码块之一来执行
function exchange (num) {
  if (num && typeof num == 'number') {
    //typeof num=='number' && 0<num and num<=10
    if (num > 0 && num <= 10) {
      if (num == 1) {
        result = "壹";
      } else if (num == 2) {
        result = "贰";
      } else if (num == 3) {
        result = "叁";
      } else if (num == 4) {
        result = "肆";
      } else if (num == 5) {
        result = "伍";
      } else if (num == 6) {
        result = "陆";
      } else if (num == 7) {
        result = "柒";
      } else if (num == 8) {
        result = "捌";
      } else if (num == 9) {
        result = "玖";
      } else {
        result = "拾";
      }
    } else if (num > 10) {
      result = "请输入不大于10的数字";
    } else {
      result = "请输入不小于0的数字";
    }
  } else if (num == 0) {
    result = "零";
  } else {
    result = "请输入数字";
  }
  console.log(result);
}
exchange(0);//零
exchange(-120);//请输入不小于0的数字 
exchange(100);//请输入不大于10的数字
exchange('as');//请输入数字
exchange();//请输入数字

switch

首先设置表达式 n(通常是一个变量)。随后表达式的值会与结构中的每个 case 的值做比较。如果存在匹配,则与该 case 关联的代码块会被执行。请使用 break 来阻止代码自动地向下一个 case 运行

var day = new Date().getDay();
switch (day) {
  case 4:
    console.log("今天是星期四");
  case 5:
    console.log("今天是星期五");
  default:
    console.log("期待周末")
}

default 关键词来规定匹配不存在时做的事情;
case代码块中break不能省略;
default可以放到代码任意位置,break不能省略;最后位置可以省略break;

循环语句

关键字:break
如果想在所有迭代前退出,即可使用break。当执行break后,会立即跳出循环体。
关键字:continue
continue不会跳出循环。而是立即结束当前循环,进入下一次循环。

For 循环

for (*语句 1*; *语句 2*; *语句 3*)
{
  *被执行的代码块*
}
for (var i=0; i<5; i++)
{
    console.log(i);
}

while 循环

while (*条件*)
{
  *需要执行的代码*
}
while (i<5)
{
    console.log(i);
    i++;
}

do/while 循环

var result = 0;
var i = 1;
do{
	result += i;
	i++;
} while(i<=100);
console.log(result);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值