声明对象的方式/构造函数/原型/this指向

  函数的发展历程(声明函数的方式):
    1、通过Object构造函数或字面量的方式创建单个对象
var obj = new Object;
obj.name="新华";
obj.age=18;
obj.methods=function(name,age){
return "我的名字是"+name+"年龄:"+age
}
console.log(obj.name,obj.age,obj.methods("新华",18))
 
var obj = {key:val}
        2、工厂模式创建一类对象(出现函数了)
        实际是在一个函数里创建好对象后,在返回来。
function createPerson(name,age,say){
    var obj1 = new Object();
    obj1.name = name;
    obj.age = age;
    obj.say = say;
    obj.should = function(){
        alert(this.say);
    }
    return obj;
}
var person1 = createPerson('bangbang',18,'但行好事,莫问前程');
var person2 = createPerson('yanniu',18,'啥都看了房间');
    3、构造函数创建对象
function CreatePerson(name, age, say){
    this.name = name;
    this.age = age;
    this.say = say;
    this.should = function(){
        console(this.say);
    }
}
var person1 = new CreatePerson('bangbang',18,'修身,齐家,天下很太平');
var person2 = new CreatePerson('yanniu',18,'吃地沟油的命,操中南海的心');
    构造函数和工厂模式的不同:工厂模式可以创建多个对象,但不能解决对象识别问题;构造函数创建的对象,可以标识为一种特定的类型(知道对象从哪new出的)。 因为new的不同。
        检测对象的类型(左边的对象是否是右边构造函数的实例,值为true/false):obj1 instance Functon    
    构造函数和普通函数的不同:只有调用方式的不同:只要用来new 的函数就是构造函数,不用来new的就是普通的函数。   构造函数开头大写,构造函数this指向new出的对象,普通函数指向window。
        4、原型模式创建对象
            构造函数的问题:
            构造函数内部的方法会被重复创建占用空间,不同实例内的同名函数是不相等的。可通过将方法移到构造函数外部解决这一问题,但面临新问题:封装性不好。
         这些问题可通过原型模式解决。 
function Person(){
}
Person.prototype.name="Nicholas";
Person.prototype.age=29;
Person.prototype.job="...";
Person.prototype.sayName=function(){
...
};
var person1=new Person();
person1.sayName();//"Nicholas"
     我们创建的每个函数对象,都有一个prototype属性,属性里有个指针,指向一个对象叫做原型对象。原型对象中存放公共的属性和方法。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。
       原型的优点:不用在重复创建函数占用空间,但共享的结果是对象中的初始值是想等的,这个问题可以通过添加同名属性或隐藏原型属性解决,但是对于引用数据类型会出现问题,所有原型创建对象很少单独使用!
        5、原型和构造函数组合使用 创建对象
function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=["S","C"];
}
 
Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name);
}
};
var person1=new Person(...);
        构造函数内定于实例属性,原型内定于公共的方法和属性,而且可以通过构造函数传递参数。
    6、Object.create()
     ES5定义了一个名为Object.create()的方法,它创建一个新对象,其中第一个参数是这个对象的原型,第二个参数对对象的属性进行进一步描述
--------------------------------------------------------------------------------------
提到了构造函数,说一下new 构造函数实例化时(实例化就是成为对象),构造函数内部发生了什么?
    1、首先在构造函数内生成一个新的中间对象,作为最终返回的实例。(知识代码中省略没写)
    2、将这个中间对象的原型指向构造函数的原型
    3、将构造函数的this指向这个中间对象
    4、返回这个中间对象,即new出的对象
提到了函数,说下bind,apply/call的区别
    三者都是Function内置对象的方法,都是为了改变函数内部this指向。
    1、三者第一个参数是this要指向的对象,可以通过后续参数传参
    2、bind是返回一个函数,不调用不改变;call、apply是立即改变;
    3、call和apply接收参数的方式不一样,call是按照参数的先后顺序接收,apply是将参数放在数组中,接收一个数组。
        
        (call apply区别)
        var array1 = [12,'foo',{name:'Joe'},-2458];
        var array2 = ['Doe' , 555 , 100];
        Array.prototype.push.call(array1, array2);
        // 这里用 call 第二个参数不会把 array2 当成一个数组,而是一个元素
        //等价于array1.push(‘‘'Doe' , 555 , 100’’);
        //array1.length=5;
        Array.prototype.push.apply(array1, array2); // 这里用 apply 第二个参数是一个数组
        // 等价于: array1.push('Doe' , 555 , 100);
        //array1.length=7;
 
        (call或apply的使用)
        apple.say.call(null); // null是window下的,此时,this 就指向了window ,但是window下并没有clolr这个属性,因此this.clolr就是window.color=undefined;//My color is undefined。
        say函数内this指向改变为...
      
        将伪数组转为数组的方法:将数组的原型指向这个伪数组。 Array.prototype.apply(document.getElementsByClassName).
        (bind的使用)
        var bar = function(){
            console.log(this.x);
        }
        var foo = {
            x:3
        }
        bar(); // undefined
        var func = bar.bind(foo); //此时this已经指向了foo,但是用bind()方法并不会立即执行,而是创建一个新函数,如果要直接调用的话 可以 bar.bind(foo)()
        func(); // 3
提到了原型,说一下对原型链的理解?
    每一个函数对象都有一个原型对象和prototype属性,这个属性存放了指针,指向后面的原型对象;每一个对象都有一个原型对象和__proto__属性,这个属性存放指针,(Object顶级对象的原型对象指向null)
    每个原型对象身上都有一个constructors属性,指向自己的构造函数。 形成一个链条,叫做原型链。
原文地址:https://www.cnblogs.com/xixinhua/p/10429558.html