单例模式:
需要手工一个个的创造
在项目中,我们为了避免使用全局变量或者全局的方法导致的冲突问题,
我们通常把需要的方法和变量当作一个对象数据类型的属性名和属性值存起来,
每次执行的时候 对象.属姓名()就可以了 这样就解决了冲突的问题 而且我们把创建的那个对象名称之为命名空间
var p1 = {name:"张三",age:28,height:"185cm",writeCss:function(){}};
var p2 = {name:"李四",age:18,height:"153cm",writeCss:function(){}};
对象字面量写法的单例模式
var regist = {
name:"张三",
check:function(){
},
submitFn:function(){
}
};
regist.check();
闭包形式写法的单例模式
var obj=(function () {
var name='tangli';
var age=18;
function check() {
alert(name)
alert(age)
};
function submitFn(){
};
return {
name:name,
age:age,
check:check,
submitFn:submitFn
}
})();
obj.check();
工厂模式:
为了解决单例模式中一个个生产的问题,用工厂模式实现批量生产
function createJsPerson(name,age){
var obj={};
obj.name=name;
obj.age=age;
obj.writeCss=function(){
console.log("我叫"+name+",今年"+age+"岁,我会写CSS啦!");
}
obj.writeJs=function(){
console.log("我叫"+name+",今年"+age+"岁,我会写JS啦!");
}
return obj;
}
var p1 = createJsPerson("张三",28);
var p2 = createJsPerson("李四",18);
构造函数模式:
我们把执行函数的时候 用new创建的方式称之为构造函数模式(实例创建的方式)
通过这种方式,我们把原先的那个函数称之为类,把返回结果p1称之为这个类的一个实例
构造函数模式用来解决实例的差异化对象 类 实例的区别?
对象:js中万物皆对象,泛指 自然界中万物皆对象
类:对象的细分 比如:分为人类,动物类,植物类
实例:类中一个真真切切的东西 比如:我就是人类中的一个实例返回的实例也是一个对象数据类型 也就是说:new一个函数的时候,
首先会默认的创建一个对象,就是我们创建的那个实例
接下来会以实例(this)作为上下文,把对应的属性存起来,换句话说this就是我们创建的这个实例
function CreateJsPerson(name,age){
this.name=name;
this.age=age;
this.writeCss=function(){
console.log("我叫"+this.name+",今年"+this.age+"岁,我会写CSS啦!");
}
this.writeJs=function(){
console.log("我叫"+this.name+",今年"+this.age+"岁,我会写JS啦!");
}
}
var p1 = new CreateJsPerson("张三",4);
p1.writeJs();
构造函数第一个字母要大写
构造函数和工厂的区别
创建:
1、不需要手动创建obj对象了,而且也不用return obj对象了
2、原先obj统一替换成this(this是谁?)
执行:
定义变量=new 函数名(参数值)
instanceof 用来检测某一个实例是不是属于某个类的,属于返回true,相反是false
js中的内置类 Object Array String Number Math Date RegExp
console.log(p1 instanceof CreateJsPerson);
console.log(p1.writeJs==p2.writeJs); //false
构造函数模式的不足:
很多通用的方法没有实现共享,比如p1教css和js的方法应该个p2的一样才对,但是现有的模式,不能实现一样,那我们怎么办?
基于构造函数的原型链模式:产品差异化的同时,有相同的部分还可以共享
将需要共享的属性写在原型链prototype上,这样prototype上所定义的属性和方法就可以被每一个类的实例共享了
function CreateJsPerson(name){
this.name=name;
}
CreateJsPerson.prototype.writeCss=function(){
console.log(this.name+"教css");
}
CreateJsPerson.prototype.writeJs=function(){
console.log(this.name+"教js");
}
var p1 = new CreateJsPerson("张三");
var p2 = new CreateJsPerson("李四");
console.log(p1.writeJs == p2.writeJs); //true
每一个function函数都有一个天生自带的属性,叫做prototype,但是如果不是new 函数的话,这个属性没有任何意义
prototype属性存储的是一个对象数据类型,有一个自己的内存块(并且,这个内存块上有又有两个自带的属性 constructor proto)
constructor是prototype这个对象数据类型特有的,而proto是所有对象数据类型都有的
当我们new一个函数的时候,函数变成了类,并且返回一个实例,这个实例是对象数据类型的,所以有proto这个自带的属性,并且这个属性指向的是我们的函数(类)里面prototype自己的那个内存地址
所以,我们的实例p1除了拥有函数里面自带的name属性(私有属性)外,同时还拥有了函数prototype上定义的属性(共有属性)
function Fn(name){
this.name=name;
this.num=4;
this.writeCss=function(){
console.log(1);
}
}
var proto = Fn.prototype;
proto.writeJs=function(){
console.log(this);
}
proto.writeCss=function(){
console.log(2);
}
p1.writeCss(); //输出1
我们在调用实例上的属性名的时候,遵循这样的顺序:先找私有的,私有的没有,在通过proto找他所在类的原型上的属性,如果在私有的中找到了,就不在找了
我们要想找共有的
p1.__proto__.writeCss(); //输出2
console.log(p1.hasOwnProperty("writeCss")); //true
console.log(p1.hasOwnProperty("writeJs")); //false
hasOwnProperty用来检测某个实例上是否存在某个属性(是私有的属性此才有效,原型链上的无法检测)
console.log(Fn.prototype.isPrototypeOf(p1)); //true
检查某个实例是否在这个类的原型链上
js中我们常用的this有这几种情况
给元素绑定事件 oDiv.οnclick=function(){ //this就是oDiv}
(function(){ //this是window })(); //闭包
函数执行前的主体 fn()–>window
obj.fn()–>obj //当以构造函数运行的时候,this就是我们创建的那个实例