一.数据类型
在javascript当中数据类型总共分为两类:基本类型和引用类型;基本类型是有6种分别是:null,undefined,boolean,number,string和symbol(es6新增,表示独一无二的值,具体可以看阮一峰的介绍);引用类型统称为Object对象,主要包括对象,数组.
基本类型和引用类型的区别:
主要是存储位置不一样,基本类型直接存储在栈当中,而引用类型只是把指针存储在栈中,对应的值是存储在堆中的.
数据类型检测方法:
方法1:typeof
除了null,其它都可以检查;
方法2:A(对象) instanceof B(构造函数)
判断这个构造函数的prototype属性, 在不在这个对象的原型链上.。如果在则返回true,否则返回false。比如:console.log([] instanceof Array);//true(检测方法不准确,因为[] instanceof Object)也是true;
方法3:Object.prototype.toString.call(传入要检测的数据)
这个方法是万能的检测数据类型,比如:console.log(Object.prototype.toString.call(null)); //’[object Null]’
方法4:Array.isArray([])
这是数组单独的检测方法,比如:console.log(Array.isArray([]))//true
二.预解析
预解析的规律:
1.把变量的声明提升到当前作用域的最前面,只会提升变量的声明,不会提升赋值;
2.把函数的声明提升到当前作用域的最前面,只会提升函数的声明,不会提升调用;
3.在同一级作用域里存在变量声明和函数声明,优先会提升变量声明;
演示代码1:
var a = 25;
function abc (){
alert(a);//undefined
var a = 10;
}
abc();
console.log(a);//25
function a() {
console.log('aaaaa');//没有调用,不会执行
}
var a = 1;
console.log(a);//1
预解析会变为:
var a;
function abc (){
var a;
alert(a);//undefined
a = 10;
}
function a() {
console.log('aaaaa');//没有调用,不会打印
}
a = 25;
abc();
console.log(a);//25
a = 1;
console.log(a);//1
演示代码2:(涉及多个赋值的拆解)
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
预解析后变为:
function f1() {
//注意多个赋值拆解规律:变量声明第一,最后赋值第二,依次后往前的规律赋值
var a;
c=9;
b=c;
a=b;
console.log(a);//9
console.log(b);//9
console.log(c);//9
}
f1();
console.log(c);//9
console.log(b);//9
console.log(a);//只有局部f1里才有,全局里没有,直接报错
三.对象
创建对象的方法
引言:我平时项目中一般四种方法比较常用,但我看了<<javascript高级程序设计>>这本书之后发现有9种方法,分别是:
1.字面量方法:
var person = {
name: "小明",
age: 18,
sayHi: function () {
console.log("hi");
}
}
console.log(person);
2.new Object()创建方法:
var person =new Object();
person.name="小明";
person.age=18;
person.sayHi=function(){
console.log("hi");
}
console.log(person);
3.工厂模式创建对象方法:(是new Object()创建的升级,实际是封装函数后将对象返回出来)
function createPerson(name,age,logData){
var person =new Object();
person.name=name;
person.age=age;
person.sayHi=function(){
console.log(logData);
}
return person;
}
var person=createPerson('小明',18,"hi")
console.log(person);
4.构造函数方法:
function Person(name,age,logData){
this.name=name;
this.age=age;
this.sayHi=function(){
console.log(logData);
}
console.log(this);//this是对象本身
}
var person=new Person('小明',18,"hi")
console.log(person);
构造函数写法两个注意点:
a.函数首字母要大写;
b.要使用new关键字;
构造函数new关键字做的四件事:
提示:结合工厂函数和构造函数对比发现
a.new会在内存中用new Object()方法创建一个新的空对象;
b.new会让this指向这个心的空对象;
c.执行构造函数,给这个新的空对象添加属性和方法;
d.最后,new会将有值的新对象进行返回;
注意:
因为new关键字会自动帮我们返回他创建的对象,所以一般在构造函数中是不用写return返回值的, 那万一构造函数中就是写了return返回值,这样看返回值是简单类型还是引用类型,简单类型不影响,如果是复杂类型,那么这个返回值会覆盖原来new关键字自动返回的那个对象,这样使创建的对象直接变为复杂类型值.
5.原型链方法:也是使用了构造函数,但构造函数参数和函数体都是空,我们直接在函数点prototype点加要添加的属性名=值;
function Person() {
}
Person.prototype.name = "小明";
Person.prototype.age = 18;
Person.prototype.sayHi = function () {
console.log("hi");
}
var person = new Person();
console.log(person);//它会从原型里找到
6.构造函数和原型链组合方法:(实际就是一部分属性写在构造函数里,一部分属性写在原型里)
function Person(name) {
this.name = name