JavaScript面向对象
基本类型
- 
Undefined 
- 
Null 
- 
Boolean 
- 
Number 
- 
String 
引用类型
- 
- 
Array 
- 
Date 
- 
RegExp 
- 
Function 
- 
基本包装类型 - 
Boolean 
- 
Number 
- 
String 
 
- 
- 
单体内置对象 - 
Global 
- 
Math 
 
- 
类型判断
- 
typeof 
- 
instanceof 
- 
Object.prototype.toString.call() 
差别
- 
基本类型在内存中占据固定大小的空间, 因此保存在栈内存中 
- 
基本类型变量的赋值,复制的就是值得副本 
- 
引用类型的值是对象,保存在堆内存 
- 
包含引用类型值得变量实际上包含的不是对象的本身,二十一个指向对象的指针 
- 
引用类型进行赋值的时候, 复制的是引用指针, 两个变量指向同一对象 
小结
- 
类型检测方式 
- 
基础类型和引用类型复制, 以及存储方式 
- 
方法中 数据传递 
JavaScript执行流程
预解析
- 
全局预解析(变量和函数提前声明, 同名的函数比变量函数优先级高) 
- 
函数内部预解析(所有的变量,函数和形参都会参与预解析) - 
函数 
- 
形参 
- 
普通变量 
 
- 
执行
- 
先解析全局作用域,然后执行全局作用域中的代码 
- 
在执行全局代码中遇到的函数, 遇到函数就进行函数的预解析,在执行函数内代码 
JavaScript面向对象
封装, 继承, 多态
创建对象
简单方式
var person = new Object();
person.name = "Jack";
person.age = 18;
person.sayName = function(){
    console.log(this.name);
}
var person = {
    name: "jack",
    age: 18,
    sayName: function(){
        console.log(this.name);
    }
}
改进:工厂函数
function createPerson(name, age){
    return {
        name: name,
        age: age,
        sayName: function(){
            console.log(this.name);
        }
    }
}
实例化对象
var p1 = createPerson("jack", 18);
var p2 = createPerson("luck", 20);
构造函数
function Person(name, age){
    this.name = name;
    this.age = age;
    this.sayName = function(){
        console.log(this.name);
    }
}
// 实例化对象
var p = new Person("jack", 18);
p.sayName(); // jack
解析构造函数的执行
创建Person实例, 则必须使用 new操作符
- 
创建一个新对象 
- 
将构造函数的作用域赋值给新对象(this指的是这个新对象) 
- 
执行构造函数中的代码 
- 
返回新对象 
构造函数和实例对象之间的关系
使用构造函数在于代码的简洁性,更重要的就是识别对象的具体类型。
在每一个实例对象中的_proto_中同时有一个constructor属性,该属性指向创建该实例的构造函数:
console.log(p1.constructor === Person);// true
console.log(p2.constructor === Person);//true
console.log(p1.constructor === p2.constructor);  // true
对象的constructor属性最初用来标识对象类型的, 但是检测类型还是使用instanceof操作符可靠一点
console.log(p1 instanceof Person); // true
console.log(p2 instanceof Person); // true
总结
- 
构造函数是根据具体的事物抽象出来的抽象模板 
- 
实例对象是根据抽象的构造函数模板得到的具体实例对象 
- 
每一个实例对象都具有一个 constructor属性, 指向该实例的构造函数- 
注意: constructor是实例的属性的说法不严谨
 
- 
- 
可以通过实例的 constructor属性进行判断实例和构造函数之间的关系- 
注意: 这种方法不严谨, 推荐使用 instanceof。
 
- 
构造函数的问题
使用构造函数方便创建对象, 但是有时候存在浪费内存
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.type = "human";
    this.sayHello = function() {
        console.log("hello" + this.name);
    }
}
var p1 = new Person("jack", 18);
var p2 = new Person("luck", 18);
对于p1和p2两个对象而言,type和sayHello都是一模一样的内容,造成了内存浪费
console.log(p1.sayHello === p2.sayHello); // false
对于这种问题,将共享的函数定义到构造函数外部
sayHello = function() {
    console.log('hello'+this.name)
};
function Person (name, age) {
    this.name = name;
    this.age = age;
    this.type = 'human';
    this.sayHello = sayHello;
}
var p1 = new Person('lpz', 18);
var p2 = new Person('Jack', 16);
console.log(p1.sayHello === p2.sayHello) // => true
避免全局变量命名空间冲突问题, 进行改写
var fns = {
    sayHello: function() {
      console.log('hello'+this.name);
    },
    sayAge: function() {
      console.log(this.age);
    },
};
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.type = "human";
    this.sayHello = fns.sayHello;
    this.sayAge = fns.sayAge;
}
var p1 = new Person("jack", 18);
var p2 = new Person("luck", 18);
console.log(p1.sayHello === p2.sayHello); // true
console.log(p1.sayAge === p2.sayAge); //true
 
                    
                     
                    
                 
                    
                 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号