//数组内置类: Array 每个数组都是数组内置类的实例
//对象内置类: Object 每个对象数据类型都是对象内置类的实例
//函数内置类: Function 每个函数都是函数内置类的实例
//Js中除了内置类 项目中也须要自定义类
复制代码
function createJsPerson() {
var obj = {};
obj.name = name;
obj.writeJs = function() {
console.log("my name is " + this.name + ",i can write js la");
}
return obj;
}
var p1 = createJsPerson("A",18);
p1.wrireJs();
//p1 是对象数据类型的 createJsPerson 是函数名 方法名
//经过函数的执行 返回一个对象
复制代码
function CreateJsPerson(name,age) {
this.name = name;
this.age = age;
this.writeJs = function() {
console.log("my name is " + this.name + ",i can write js la");
}
}
//不用再定义obj 也不用再return obj
var p2 = new CreateJsPerson("A",18);// CreateJsPerson就是类
p2.writeJs();
复制代码
一、执行的时候 普通函数执行(工厂模式) ---> createJsPerson() 构造函数模式 ---> new CreateJsPerson() 经过new执行后,咱们的CreateJsPerson就是一个类了(为了和内置类有同样的标准,首字母建议大写),而函数执行的返回值P2就是CreateJsPerson这个类的一个实例javascript
//建立一个数组
var array = [] //字面量方式
var array = new Array();//实例建立的方式 ---> 构造函数模式执行的方式
//无论哪种方式建立数组 array都是Array这个类的一个实例
复制代码
二、在函数代码执行的时候 相同:都是造成一个私有的做用域,而后形参赋值 -->预解释 --> 代码从上往下执行(类也有普通函数的一面) 不一样:在代码执行以前,构造函数不用再本身建立对象,浏览器会默认建立一个对象数据类型的值(这个对象其实就是咱们当前类的一个实例),而后代码从上往下执行,以当前实例为执行的主体(this就是当前的实例),而后分别把属性名和属性值赋给当前实例java
function CreateJsPerson(name,age) {
this.name = name; //---> this表明当前隐形的对象
this.age = age;
this.writeJs = function() {
console.log("my name is " + this.name + ",i can write js la"); //this ---> p1 表明当前实例
}
// 把属性名和属性值赋值给当前实例 不用再定义obj 也不用return obj
}
var p1 = new CreateJsPerson("A",18);
p1.writeJs();
复制代码
三、this的第4点 在构造函数模式中,类中(函数体中)出现的this.xxx = xxx中的this是当前类的一个实例数组
四、虽然p1和p2都是CreateJsPerson 这个类的实例,因此都拥有writeJs这个方法,可是不一样实例之间的方法是不同的浏览器
五、var res = CreateJsPerson("B",19);函数
function Fn() {
var num = 100;
this.x = 100;
this.getX = function() {
console.log(this.x);
}
}
var f1 = new Fn;
var f2 = new Fn;
复制代码
在构造函数模式中,new Fn()执行,若是Fn不须要传递参数的话,后面的小括号能够省略学习
this问题,在类中出现的this.xxx = xxx;中的this都是当前类的一个实例ui
而某一个属性值(方法),方法中的this须要看方法执行的时候,前面是否有"." 才知道this是谁,this
f1.getX() ---> this指f1,输出100spa
var ss = f1.getX(); ss() ---> this 指window --->输出undefined3d
console.log(f1.num) // --->输出undefined
类有普通函数的一面,当函数执行的时候,var num 其实只是当前形式的私有做用域中的私有变量而已,它和咱们的f1这个实例没有任何关系,只有this.xxx = xxx才至关于给f1这个实例增长私有的属性和方法,才和咱们的f1有关系
在构造函数模式中,浏览器会默认把咱们的实例返回,返回的是一个对象数据类型的值,若是咱们本身加了return语句,返回的是一个基本数据类型的值,当前实例是不变的,例如return 100;咱们的f1仍是当前Fn类的实例,若是返回的是一个引用类型的值,当前实例会被本身返回的值给替换掉,例如return { name: 100},咱们的f1就再也不是fn的实例了,而是对象 {name:100}
检测某一个实例是否属于这个类,--->instanceof console.log(f1 instanceof Fn) //true console.log(f1 instanceof object) //true
由于全部的实例都是对象数据类型的,并且每个对象的数据类型都是object这个内置类的一个实例,因此f1也是它的一个实例
对于检测数据类型来讲,typeof有本身的局限性,不能细分object下的对象、数组、正则 。。。。。
var a = [];console.log(a instanceof Array) //true 说明a是一个数组
f1和f2都是fn这个类的一个实例,都拥有x和getX两个属性,可是这两个属性都是各自的私有属性,因此console.log(f1.getX === f2.getX) //false
"in" 检测某一属性是否属于这个对象,attr in Object,console.log("getX" in f1);//true getX是f1的一个私有属性
(attr in object) 不论是私有属性仍是共有属性,只要存在,用in来检测都是ture
hasOwnProperty:用来检测某一个属性是否为这个对象的"私有属性",这个方法只能检测私有的属性 console.log(f1.hasOwnProperty("getX") )//true 由于getX是f1的私有属性
扩展思考:检测某一个属性是否为对象的"公有属性"
function hasPubProperty() {
return (attr in obj) && !obj.hasOwnProperty(attr)
//首先 保证是它的一个属性 而且还不是私有属性 那么只能是公有的属性了
}
复制代码