前提引入~
一个人称小仙女的妹子和一个苦逼埋头敲代码的程序猿的对话:
妹子:你缺对象吗
程序猿:缺对象还不简单么,自己创建一个就好了
所以在座的各位没有对象的,赶快new起来。
思考:
如何创建对象???
new 操作符 + Object 创建对象
var person = new Object();
person.name = "lisi";
person.age = 21;
person.family = ["lida","lier","wangwu"];
person.say = function(){
alert(this.name);
}
字面式创建对象
var person ={
name: "lisi",
age: 21,
family: ["lida","lier","wangwu"],
say: function(){
alert(this.name);
}
};
构造函数模式
function Person(name,age){//创建特定类型的对象,通过创建构造函数定义自定义对象类型的属性和方法
this.name=name;//直接将属性和方法赋给this对象
this.age=age;
this.sayName=function(){
alert(this.name);
}
};
var person1=new Person('zhangsan',20);
var person2=new Person('wangwu',15);
原型模式
//创建的每个函数都有prototype属性,该属性既个指针,指向一个对象,这个对象包含了所有的实例共享属性以及方法
function Person(){};//创建一个空的构造函数
Person.prototype.name='zhangsan';//将属性和方法添加到原型对象里
Person.prototype.age=20;
Person.prototype.sayName=function(){
alert(this.name);
}
var person1=new Person();
person1.sayName(); //zhangsan
var person2=new Person();//再创建原型实例,实例对象就拥有了原型对象的属性和方法
person2.sayName(); //zhangsan
组合构造函数模式和原型模式
function Person(name,age){ //构造函数模式
this.name=name;
this.age=age;
this.friends=['shelly','lucy'];
};
Person.prototype.sayName=function(){ //原型模式
alert(this.name);
}
var person1=new Person('zhangsan',20); //构造函数模式
var person2=new Person('wangwu',15);
person1.friends.push('van');
alert(person1.friends); //shelly,lucy,van
alert(person2.friends); //shelly,lucy
//混合模式共享着对相同方法的引用,又保证了每个实例有自己的私有属性,最大限度的节省了内存。
动态原型模式
//通过开关 动态添加函数的方法
<body>
<button onclick="fn()">点击 增/删 sayName方法</button>
<button onclick="xh()">点击实例化 小红 对象</button>
<script>
let flag = false;
let xiaohong;
function Person(name, age, gender) {
//凡是后期需要修改的值 都放在构造函数的this.属性名称的方式来实现继承
this.name = name;
this.age = age;
this.gender = gender;
this.like = ['小猫', '小狗', '小鸟'];
//刚开始flag = false 所以实例化出来的方对象没有sayName方法
if (flag) {
Person.prototype.sayName = function() {
console.log(this.name);
}
} else {
Person.prototype.sayName = null;
}
}
function fn() {
flag = !flag;
}
function xh() {
xiaohong = new Person('小红', 16, '女');
console.log(xiaohong);
}
//console.log(Person);
</script>
</body>
工厂模式
function createPerson(){//使用函数来封装,看作为普通函数
var o = new Object();
o.name = name;
o.sayName = function () {
alert(this.name);
}
return o;//有返回值
}
var person1 = new createPerson('zhangsan');
var person2 = new createPerson('wangwu');
寄生构造函数模式
//除了使用new操作符并把使用的包装函数叫做构造函数之外,这个模式跟工厂模式其实是一模一样的。构造函数在不返回值的情况下,默认会返回新对象实例。而通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值。
function Person(name, age, job) {//被看作为构造函数
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function() {
alert(this.name);
}
return o;
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
var person2 = new Person("Greg", 27, "Doctor");
稳妥构造函数模式
function DurablePerson(name, age, job) {
var o = new Object();
o.say = function () {
document.write("Hello,I'm " + name + "," + age + " years old,i'm a " + job + "。<br/>"); //注意:不使用this,而使用参数传入的变量
}
return o;
}
//与寄生构造函数模式有些类型,但不同点有二:1,构造函数内部不使用this;2,创建对象实例不使用new
var person4 = DurablePerson("james", 29, "Ball Star");
//使用稳妥构造函数模式的优点是安全性。P161
//这种模式创建的实例也不能正确检测其类型:
document.write(person4 instanceof DurablePerson); //false
document.write(" --- ");
document.write(person4.constructor == DurablePerson); //false
document.write("<br/>");
document.write(person4 instanceof Object); //true
document.write(" --- ");
document.write(person4.constructor == Object); //true
document.write("<br/>");