js是一种解释性语言,不需要编译,直接由浏览器解析执行
js的出现使得页面有了交互功能,js的出现才使得网页真正意义上实现了网络的互联和交互。例如淘宝购物,h5小游戏以及一些3D大屏的动态展示,这些都是js在现实网络中的生动体现
js由上往下,由左往右,由浏览器解析执行
js可以写在html文档的任何地方,一个文档可以写多个script标签
内部引入建议写在body结束标签之前,外部引入写在head标签里面
内部引入和外部引入不能共用一个script标签
//单行注释
/**
* 多行注释
* 多行注释
*/
可以改变的量叫做变量,存储信息的容器,实质就是申请内存。并将该块内存赋值
声明一个变量没有赋值,默认为undefined(未定义),没有声明变量直接输出,则报错
一条语句可以声明多个变量,用逗号,隔开
js中重新赋值,后面的值会替换掉前面的值
var/let/const 三者声明变量的不同在es6专栏介绍
Number
包含所有数字(整数,小数,正数,负数,极大极小数,),NaN,Infinity
let intNum = 55 // 10进制的55
let num1 = 070 // 8进制的56
let hexNum1 = 0xA //16进制的10
let floatNum1 = 1.1;
let floatNum2 = 0.1;
let floatNum3 = .1; // 有效,但不推荐
let floatNum = 3.125e7; // 等于 31250000
console.log(0/0); // NaN
console.log(-0/+0); // NaN
console.log(Number.MAX_VALUE); //1.7976931348623157e+308
console.log(Number.MAX_SAFE_INTEGER); //9007199254740991
console.log(Number.EPSILON); //2.220446049250313e-16
console.log(Number.MIN_SAFE_INTEGER); //-9007199254740991
console.log(Number.MIN_VALUE); //5e-324
数值最常见的整数类型格式则为十进制,还可以设置八进制(零开头或0O开头)、十六进制(0x开头)
浮点类型则在数值汇总必须包含小数点,还可通过科学计数法表示
在数值类型中,存在一个特殊数值NaN,意为“不是数值”,用于表示本来要返回数值的操作失败了(而不是抛出错误)
String
let firstName = "猿起";
let lastName = '猿落';
let lastName = `猿起猿落`
let lang = "Java";
lang = lang + "Script"; // 先销毁再创建
字符串可以使用双引号(")、单引号(')或反引号(`)标示
字符串是 不可变的,意思是一旦创建,它们的值就不能变了
Boolean
只包含两个值:true和false
通过Boolean可以将其他类型的数据转化成布尔值,规则如下:
数据类型 转换为 true 的值 转换为 false 的值
String 非空字符串 ""
Number 非零数值(包括无穷值) 0 、 NaN
Object 任意对象 null
Undefined N/A (不存在) undefined
参与数学运算时:true转换为1,false转换为0
Undefined
该类型只有一个值,就是特殊值undefined
。当使用var
或let
声明了变量但没有赋值时,就相当于给变量赋予了undefined
值
let message;
console.log(message == undefined); // true
包含undefined
值的变量跟未定义变量是有区别的
let message; // 这个变量被声明了,只是值为 undefined
console.log(message); // "undefined"
console.log(age); // 没有声明过这个变量,报错
Null
该类型同样只有一个值,即特殊值null
逻辑上讲, null 值表示一个空对象指针,这也是给typeof
传一个null
会返回"object"
的原因
let car = null;
console.log(typeof car); // "object"
undefined
值是由null
值派生而来
console.log(null == undefined); // true
只要变量要保存对象,而当时又没有那个对象可保存,就可用null来填充该变量,undefined和null表现效果一样,但undefined用于变量(基本)类型,null用于对象类型
null一般用来释放对象的,给对象初始化
Symbol
Symbol (符号)是原始值,且符号实例是唯一、不可变的。符号的用途是确保对象属性使用唯一标识符,不会发生属性冲突的危险,具体见es6专栏
let genericSymbol = Symbol();
let otherGenericSymbol = Symbol();
console.log(genericSymbol == otherGenericSymbol); // false
let fooSymbol = Symbol('foo');
let otherFooSymbol = Symbol('foo');
console.log(fooSymbol == otherFooSymbol); // false
复杂类型统称为Object,我们这里主要讲述下面三种
Object
创建Object常用方式为对象字面量表示法,属性名可以是字符串或数值
let person = {
name: "Nicholas",
"age": 29,
5: true
};
console.log(person['5']); //true
键名是数字时,访问用方括号访问
Array
数组是一组有序的数据,但跟其他语言不同的是,数组中每个槽位可以存储任意类型的数据。并且,数组也是动态大小的,会随着数据添加而自动增长
let colors = ["red", 2, {age: 20 }]
colors.push(2)
Function
函数实际上是对象,每个函数都是Function
类型的实例,而Function
也有属性和方法,跟其他引用类型一样
函数存在三种常见的表达方式:
// 函数声明
function sum (num1, num2) {
return num1 + num2;
}
//函数表达式
let sum = function(num1, num2) {
return num1 + num2;
};
//箭头函数
let sum = (num1, num2) => {
return num1 + num2;
};
除了上述说的三种之外,还包括Date
、RegExp
、Map
、Set
等......
typeof
返回一个字符串,表示未经计算的操作数的类型
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'
由以上可知:typeof一般用来判断基本数据类型,虽然typeof null
为object
,但这只是JavaScript
存在的一个悠久Bug
,不代表null
就是引用数据类型,并且null
本身也不是对象,同时,可以发现引用类型数据,用typeof
来判断的话,除了function
会被识别出来之外,其余的都输出object
instanceof
运算符用于检测构造函数的prototype
属性是否出现在某个实例对象的原型链上
构造函数通过new
可以实例对象,instanceof
能判断这个对象是否是之前那个构造函数生成的对象
// 定义构建函数
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('xxx')
car instanceof String // true
let str = 'xxx'
str instanceof String // false
以上可知:instanceof返回的是一个布尔值,可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
通用检测数据类型
Object.prototype.toString,调用该方法,统一返回格式“[object Xxx]”
的字符串
Object.prototype.toString({}) // "[object Object]"
Object.prototype.toString.call({}) // 同上结果,加上call也ok
Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call('1') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call(undefined) //"[object Undefined]"
Object.prototype.toString.call(/123/g) //"[object RegExp]"
Object.prototype.toString.call(new Date()) //"[object Date]"
Object.prototype.toString.call([]) //"[object Array]"
Object.prototype.toString.call(document) //"[object HTMLDocument]"
Object.prototype.toString.call(window) //"[object Window]"
实现一个全局通用的数据类型判断方法
function getType(obj){
let type = typeof obj;
if (type !== "object") { // 先进行typeof判断,如果是基础数据类型,直接返回
return type;
}
// 对于typeof返回结果是object的,再进行如下的判断,正则返回结果
return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');
}
使用如下
getType([]) // "Array" typeof []是object,因此toString返回
getType('123') // "string" typeof 直接返回
getType(window) // "Window" toString返回
getType(null) // "Null"首字母大写,typeof null是object,需toString来判断
getType(undefined) // "undefined" typeof 直接返回
getType() // "undefined" typeof 直接返回
getType(function(){}) // "function" typeof能判断,因此首字母小写
getType(/123/g) //"RegExp" toString返回
声明变量时不同的内存地址分配
不同的类型数据导致赋值变量时的不同
引用类型数据存放在堆中,每个堆内存对象都有对应的引用地址指向它,引用地址存放在栈中。
var obj1 = {}
var obj2 = obj1;
obj2.name = "Xxx";
console.log(obj1.name); // xxx
下图演示这个引用类型赋值过程