一、基础数据类型
1.原始数据类型 数字(number)、字符串(string)、布尔值(Boolean)、null(空)、undefined(未定义)、Symbol(表示独一无二的值符号) | 2.对象类型 数组(Array)、函数(Function)、正则(RegExp)和日期(Data) |
二、判断js的数据类型的方法(四种)
typeof "Emma" ----string
typeof 3.14 -----number
typeof flase ---- Boolean
typeof [1,2,3] ---- object
typeof {name:'Emma',age:18} --- object
typeof myCar ----undefined (如果没有myCar声明)
typeof NaN ---- number
typeof undefined --- undefined
typeof null 为什么返回object?
在判断数据类型的时候,是根据机器码地位标识来判断,null的机器标识码为全0, 而对象的机器码低位标识为000,,所以typeof null的结果被误判为object。
typeof的缺点是什么?
typeof不能判断具体的引用数据类型
判断具体引用类型的方式?
instanceof
instanceof的原理是什么?----js对象---原型、原型链、继承??
instanceof只能正确判断引用数据类型,而不能判断基本数据类型
a instanceOf (b) ---- b的prototyp原型对象是否在a的原型链上
1)instanceof的用法
instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。
//测试数据类型
console.log('测试 Number ->', 1 instanceof Number); // false
console.log('测试 Boolean ->', true instanceof Boolean); // false
console.log('测试 String ->', '' instanceof String); // false
// console.log('测试 null ->', null instanceof null); // TypeError: Cannot read property 'constructor' of null
// console.log('测试 undefined ->', undefined instanceof undefined); // TypeError: Cannot read property 'constructor' of undefined
console.log('测试 NaN ->', NaN instanceof Number); // false
console.log('测试 function ->', function () { } instanceof Function); // true
console.log('测试 Object ->', {} instanceof Object); // true
console.log('测试 Array ->', [] instanceof Array); // true
console.log('测试 Date ->', new Date() instanceof Date); // true
console.log('测试 Error ->', new Error() instanceof Error); // true
console.log('测试 RegExp ->', new RegExp() instanceof RegExp); // true
console.log('测试 Symbol ->', Symbol() instanceof Symbol); // false
console.log('测试 Map ->', new Map() instanceof Map); // true
console.log('测试 Set ->', new Set() instanceof Set); // true
console.log('测试 new Number ->', new Number(1) instanceof Number); // true
console.log('测试 new Boolean ->', new Boolean(true) instanceof Boolean); // true
console.log('测试 new String ->', new String('') instanceof String); // true
2)实现instanceof
function _instanceof(obj,type){
// 获取对象的原型
let proto = Object.getPrototypeOf(obj)
// 获取construct的prototype对象
let prototype = type.prototype
// 如果当前层没找到就到下一层去找
while(true){
// 如果没有原型证明不是引用数据类型
if(!proto) return false
// 如果参数对象中的对象原型等于类型构造函数的prototype对象
if(proto === prototype) return true
// 如果没有找到,就继续逐层往上层原型上找
proto = Object.getPrototypeOf(proto)
}
}
更好的判断数据类型的方法?(Object.prototype.toString.call)
console.log(Object.prototype.toString.call(1))// [object Number]
console.log(Object.prototype.toString.call('Hello tomorrow')) // [object String ]
console.log(Object.prototype.toString.call(true))// [object Boolean]
console.log(Object.prototype.toString.call(undefined))// [object Undefined]
console.log(Object.prototype.toString.call(function(){}))// [object Function]
console.log(Object.prototype.toString.call(new Date)) // [object Date]
console.log(Object.prototype.toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call([1, 2, 3])) // [object Array]
console.log(Object.prototype.toString.call({ a: 1, b: 2 })) // [object Object]
console.log(_instanceof([1,2,3],Array)); //true
console.log(_instanceof([1,2,3],Function)); //fasle
其他判断(construct)
console.log((9).constructor === Number); //true
console.log('hello'.constructor === String); //true
console.log(true.constructor === Boolean); //true
console.log(fn.constructor === Function); //true
console.log((new Date).constructor === Date); //true
console.log(obj.constructor === Object); //true
console.log([1, 2, 3].constructor === Array); //true
三、类型转换
转化为字符串
//变量.toString()
var num = 123
var str = num.string()
//String(变量)
var num = 10
console.log(typeof(String(num)))
//隐式转换
console.log(num+'')
转化成数字型parseInt()整数数值类型
var age = prompt('请输入年龄')
console.log(parseInt(age))
//2.转化成浮点数数值类型parseFloat()
console.log(parseFloat(age))
//3.Number(变量)
//4.利用算数运算隐式转换为数值型+ - * /
转化为布尔型Boolean(变量)
console.log(Boolean(123))
四、包装对象
包装对象指数值(Number)、字符串(String)、布尔值(Boolean)这三个原生对象可以把原始类型的值包装成对象。
//构造函数用New
var v1 = new Number(123);
var v2 = new String('abc');
var v3 = new Boolean(true);
typeof v1 // "object"
typeof v2 // "object"
typeof v3 // "object"
v1 === 123 // false
v2 === 'abc' // false
v3 === true // false
const str ='xxx'
str.splice()
//执行原理
const str = new String('')
str.splice()
str回归
五、变量作用域
作用域(es6)
代码名字(变量)在某个范围内起效果和作用
1)全局作用域在标签中<script>var = 10
2)局部作用域(函数作用域) function fn(){}
变量作用域
1)全局变量:写在函数体外部,全局任何部分使用 var num = 10;如果在函数内部没有声明直接赋值的变量、游览器关闭时销毁
2)局部变量:写在函数内部,仅在定义的部分能够使用
function fn (形参){var num1 = 10} fn()、程序执行完毕销毁
在函数体内,局部变量的优先级高于同名变量的优先级
问:es6的let、const -----let、const、var定义的变量什么区别?
1)var 声明的变量为函数作用域、而let、const声明的变量属于块级作用域
2)var声明的变量存在变量提升,let const没有
var a = 1; //此处声明的变量a为全局变量
function foo(){
var a = 2;//此处声明的变量a为函数foo的局部变量
console.log(a);//2
}
foo();
console.log(a);//1
//省略var的话,该变量变成全局变量
var a = 1; //此处声明的变量a为全局变量
function foo(){
a = 2;//此处的变量a也是全局变量
console.log(a);//2
}
foo();
console.log(a);//2
3)var声明的变量可以重复声明,而在同一块级作用域,
let变量不能重新声明,const常量不能修改(对象)
六、变量提升var | const、let没有变量提升
var的声明会在js预解析时把var的声明提升到当前作用域的最前面,意思是是指无论 var 出现在一个作用域的哪个位置,这个声明都属于当前的整个作用域,在其中到处都可以访问到。只有变量声明才会提升,对变量赋值并不会提升。
console.log(a);//undefined
var a = 1;
相当于执行以下代码
var a;
console.log(a);//undefined
a = 1;
2.const x = ()=>{}
x()---------yes
y()
function y(){}------yes
1)var | const、let没有变量提升
1.Let声明的变量只在let命令的代码块内有效且只能声明一次,var可以声明多次
2.let、const未声明前会造成暂时性死区
七、表达式和运算符
原始表达式
是表达式最小单位--不再包含其他表达式 ,原始表达式包含常量或直接量,关键字和变量
1.直接量的例子 1.22---数字直接量 “hello” ----- 字符串直接量 /pattern/ -----正则表达式直接量 | 2.js中的一些保留字构成了原始表达式 true -----返回一个真布尔值 false --- 返回一个假布尔值 null ---返回一个值:空 this ---- 返回当前对象 | 3.第三种原始表达式是变量 i ---- 返回变量i的值 Sum ---- 返回sum的值 undefined --- undedined是全局变量、和null不同,他不是一个关键字 |
函数定义表达式----函数直接量
// 这个函数返回传入参数值的平方
var square = function(x) {return x * x}
属性访问表达式
//属性访问表达式得到对象属性或一个数组元素的值
expression.identifier
expression [expression]
调用表达式
f(0) //f是一个函数表达式,0是一个参数表达式
Math.max(x,y,z) //Math..max是函数,xyz是参数
a.sort()//a.sort是函数,没有参数
对象创建表达式
创建一个对象并调用一个函数(这个函数叫构造函数)