数据类型:
基本数据类型:Number、String、Boolean、undefined 、null
引用数据类型:Function、Object、Array
区别:
undefined:表示变量声明但未初始化
时的值
null:表示准备用来保存对象,还没有真正保存对象
的值。从逻辑角度看,null 值表示一个空对象指针
ECMA 标准要求 null 和 undefined 等值判断返回 true
null == undefined // true
null === undefined // false
typeof
typeof
可以用来区分除了 null 类型以外的原始数据类型
,对象类型的可以从普通对象里面识别出函数:
typeof undefined // "undefined" typeof null // "object" typeof 1 // "number" typeof "1" // "string" typeof Symbol() // "symbol" typeof function() {} // "function" typeof {} // "object" // ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。
问题一:typeof 不能识别 null,如何识别 null?
答案:如果想要判断是否为 null,可以直接使用===全等运算符来判断(或者使用下面 的 Object.prototype.toString 方法)
let a = null a === null // true问题二:typeof 作用于未定义的变量,会报错吗?
答案:不会报错,返回"undefined"。
typeof randomVariable // "undefined"问题三:typeof Number(1)的返回值是什么?
答案:"number"。注意 Number 和 String 作为普通函数调用的时候,是把参数转化为 相 应的原始数据类型,也就是类似于做一个强制类型转换的操作,而不是默认当做构造函数 调用。注意和 Array 区分,Array(...)等价于 new Array(...)
typeof Number(1) // "number" typeof String("1") // "string" Array(1, 2, 3) // 等价于 new Array(1, 2, 3)问题四:typeof new Number(1)的返回值是什么?
答案:"object"。
typeof new Number(1) // "object" typeof new String(1) // "object"
instanceof
instanceof
不能用于判断原始数据类型的数据
3 instanceof Number // false '3' instanceof String // false true instanceof Boolean // false
instanceof
可以用来判断对象的类型
var date = new Date() date instanceof Date // true var number = new Number() number instanceof Number // true var string = new String() string instanceof String // true
需要注意的是,instanceof 的结果并不一定是可靠的,因为在 ECMAScript7 规范中可以通过自定义 Symbol.hasInstance 方法来覆盖默认行为。
Object.prototype.toString Object.prototype.toString.call(3).slice(8, -1) // "Number" Object.prototype.toString.call(new Number(3)).slice(8, -1) // "Number" Object.prototype.toString.call('3').slice(8, -1) // "String" Object.prototype.toString.call(new String(3)).slice(8, -1) // "String" Object.prototype.toString.call(true).slice(8, -1) // "Boolean" Object.prototype.toString.call(new Boolean(true)).slice(8, -1) // "Boolean" Object.prototype.toString.call(undefined).slice(8, -1) // "Undefined" Object.prototype.toString.call(null).slice(8, -1) // "Null" Object.prototype.toString.call(Symbol()).slice(8, -1) // "Symbol"
由上面的示例可知,该方法没有办法区分数字类型和数字对象类型
,同理还有字符串类型和字符串对象类型
、布尔类型和布尔对象类型
另外,ECMAScript7 规范定义了符号 Symbol.toStringTag,你可以通过这个符号自定义 Object.prototype.toString 方法的行为:
'use strict' var number = new Number(3) number[Symbol.toStringTag] = 'Custom' Object.prototype.toString.call(number).slice(8, -1) // "Custom" function a () {} a[Symbol.toStringTag] = 'Custom' Object.prototype.toString.call(a).slice(8, -1) // "Custom" var array = [] array[Symbol.toStringTag] = 'Custom' Object.prototype.toString.call(array).slice(8, -1) // "Custom"
因为 Object.prototype.toString 方法可以通过 Symbol.toStringTag 属性来覆盖默认行 为,所以使用这个方法来判断数据类型也不一定是可靠的
Array.isArray Array.isArray(value)可以用来判断 value 是否是数组: Array.isArray([]) // true Array.isArray({}) // false (function () {console.log(Array.isArray(arguments))}()) // false
第一种(函数声明)
function sum1(num1, num2) { return num1 + num2; }
第二种(函数表达式)
var sum2 = function (num1, num2) { return num1 + num2; }
第三种(函数对象方式)
var sum3 = new Function("num1", "num2", "return num1+num2")
1、简单对象的创建使用对象字面量
的方式{}
创建一个对象(最简单,好理解,推荐使用)
var Cat = {} // JSON Cat.name = "kity" // 添加属性并赋值 Cat.age = 2 Cat.sayHello = function () { alert("hello " + Cat.name + ",今年" + Cat["age"] + "岁了") // 可以使用 “.” 的方式访问属性, 也可以使用 HashMap 的方式访问 } Cat.sayHello() // 调用对象的(方法)函数
2、用 function(函数)来模拟 class
2.1) 创建一个对象,相当于 new 一个类的实例(无参构造函数)
function Person() {} var personOne = new Person() // 定义一个 function,如果有 new 关键字去 "实例化" ,那么该 function 可以看作是一个类 personOne.name = "dylan" personOne.hobby = "coding" personOne.work = function () { alert(personOne.name + " is coding now...") } personOne.work()
2.2)可以使用有参构造函数来实现,这样定义更方便,扩展性更强(推荐使用)
function Pet(name, age, hobby) { this.name = name // this 作用域:当前对象 this.age = age this.hobby = hobby this.eat = function () { alert("我叫" + this.name + ",我喜欢" + this.hobby + ",也是个吃货") } } var maidou = new Pet("麦兜", 5, "睡觉") // 实例化/创建对象 maidou.eat() // 调用 eat 方法(函数)
3、使用工厂方式
来创建(Object 关键字)
var wcDog = new Object() wcDog.name = "旺财" wcDog.age = 3 wcDog.work = function () { alert("我是" + wcDog.name + ",汪汪汪......") } wcDog.work()
4、使用原型对象的方式
prototype 关键字
function Dog() { } Dog.prototype.name = "旺财" Dog.prototype.eat = function () { alert(this.name + "是个吃货") } var wangcai = new Dog() wangcai.eat()
5、混合模式
(原型和构造函数)
function Car(name, price) { this.name = name this.price = price } Car.prototype.sell = function () { alert("我是" + this.name + ",我现在卖" + this.price + "万元") } var camry = new Car("凯美瑞", 27) camry.sell()
6、动态原型
的方式(可以看作是混合模式的一种特例)
function Car(name, price) { this.name = name this.price = price if (typeof Car.sell == "undefined") { Car.prototype.sell = function () { alert("我是" + this.name + ",我现在卖" + this.price + "万元") } Car.sell = true } } var camry = new Car("凯美瑞", 27) camry.sell()
以上几种,是 javascript 中最常用的创建对象的方式
原生对象
“独立于宿主环境的 ECMAScript 实现提供的对象
”
包含:Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError
内置对象
开发者不必明确实例化内置对象,它已被内部实例化了
同样是“独立于宿主环境”。而 ECMA-262 只定义了两个内置对象,即 Global 和 Math
宿主对象
BOM 和 DOM 都是宿主对象。因为其对于不同的“宿主”环境所展示的内容不同。其实说白了就是,ECMAScript 官方未定义的对象都属于宿主对象,因为其未定义的对象大多数是自己通过 ECMAScript 程序创建的对象