js初识
js是一种解释性语言,不需要编译,直接由浏览器解析执行
组成
- ECMAScript是一种开放的,被国际上广为接收的,标准的脚本语言规范,主要描述:语法,变量,数据类型,运算符,逻辑控控制语句,关键字保留字,对象,是js的核心以及标准库
- DOM(Document Object Model):文档对象模型,处理网页内容的方法和接口,用来访问和操作HTML文档
- BOM(Browser Object Model):浏览器对象模型,规定了操作浏览器的标准,提供了内容与浏览器窗口进行交互的对象,与浏览器进行交互
作用
js的出现使得页面有了交互功能,js的出现才使得网页真正意义上实现了网络的互联和交互。例如淘宝购物,h5小游戏以及一些3D大屏的动态展示,这些都是js在现实网络中的生动体现
引入方式
- 内部引入:<script>...js代码</script>
- 外部引入:<script src="./名称.js"></script>
- 行内直接写
js由上往下,由左往右,由浏览器解析执行
js可以写在html文档的任何地方,一个文档可以写多个script标签
内部引入建议写在body结束标签之前,外部引入写在head标签里面
内部引入和外部引入不能共用一个script标签
常用的三种输出方式
- 输出到控制台 console.log()
- 输出到网页 document.write()
- 弹出警告框 window.alert() 简写为alert(),alert会阻止程序的执行
语法规范
- 大小写敏感,区分大小写
- 以换行或者分号分隔语句,建议一行只写一条语句,并以分号结尾
- 会忽略多余的空格
- js代码中一定不要出现中文符号
注释
//单行注释
/**
* 多行注释
* 多行注释
*/
变量
可以改变的量叫做变量,存储信息的容器,实质就是申请内存。并将该块内存赋值
命名规则
- 变量名明确区分大小写
- 变量名可以包含数字、字母、下划线(_)和美元符$
- 变量名不可以用数字作为开头
- 变量名不能使用系统关键字和保留字
命名规范
- 定义变量见名知意
- 多个单词组成时,驼峰式命名或者-分割
使用
- 变量声明:var/let/const 变量名称
- 变量赋值:变量名称 = 值
- 变量声明并赋值:var/let/const 变量名称 = 值
声明一个变量没有赋值,默认为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
下图演示这个引用类型赋值过程