面向对象

60 阅读4分钟

公有和私有属性

function Person(name){ ----- 构造函数
  var className = "用户对象"-----私有属性
  this.name = name;-----公有属性

  var methodname = function(){}-----私有方法
  this.methodname = function(){}-----公有方法
}

用法:
function Person(){
  var methodname = function(){}
  this.init = function(){
    this.methodname()-----公有不加this
  }
}


#config 保存当前临时变量、避免重复,减少内存
this.config = {
  btn:document.getElementById("id")
}

实例化

实例化的过程就是拷贝构造函数属性的过程,除了拷贝属性以外还自动生成constructor属性,用于识别其根据那个构造函数创建的实例。

私有不能被拷贝

#删除属性,只能删除实例化属性,不能删除原型上的属性
delete snail.attrname

使用:
	delete person.propertyname


#返回一个布尔值,指示对象自身属性中是否具有指定的属性
obj.hasOwnProperty(prop)

使用:
	//如果存在这个属性返回true,没有则false
	person1.hasOwnProperty("name")


#in--如果指定的属性在指定的对象或其原型链中,则in 运算符返回true
prop in object

使用:
	//属性不管是存在于实例对象还是原型中,只要存在就返回true,则false
	"name" in person1 

	-example:
	//判断属性是存在原型中
function hasPrototypeProperty(obj, name) {
  //判断name存在于实例中吗?true:false,得到的值然后取反。如果name存在于实例中为真,在取反为false
  //语句就不成立,也就证明name存在实例中。相反如果不存在返回false取反为true。并且 name in obj
  //前面判断了 实例中是没有name的  ,那么name in obj如果为真  就是说原型中有name属性。
  return !obj.hasOwnProperty(name) && (name in obj);
}


#for...in...--遍历可枚举的对象属性。和Object.keys的区别是for...in会遍历原型上的属性
for...in...

使用:
for (var key in object) {...}


#遍历实例对象上的可枚举属性,返回数组
Object.keys(obj)
                         
使用:
	var keys = Object.keys(Person.prototype);

                         
#返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。
Object.getOwnPropertyNames()
                         
使用:
let keys = Object.getOwnPropertyNames(Person.prototype)


#更改原型属性。
Object.defineProperty(定义属性的对象注意原型, 属性的名称, 被定义或修改的属性描述符)
                         
使用:
	Object.defineProperty(Person.prototype, "constructor", {
  		enumerable: false,-----是否可枚举,默认为false
  		value: Person-----该属性对应的值,默认undefined
  		configurable:false-----是否可配置,默认为 false
  		writable:false-----是否可重写,默认false,为true时value的值才能被修改
  		get:function(){
    		return bvalue
  		}

  		set:function(newvalue){
    		bvalue=newvalue
  		}
	})

原型

原型对象不管实例化多少次都生成一次

原型对象里的属性、方法是共享的,修改一个,都被修改

function Snail(){}

Snail.prototype={
  info:{
    name:"abc"
  }
}

var snail1 = new Snail()
var snail2 = new Snail()

snail1.info.name = "aaa";
snail2.info.name = "bbb";
console.log(snail1.info.name,snail2.info.name);//bbb bbb

//为什么输出的都是bbb???  因为snail1和snail2实例共享了Snail构造函数的原型属性info,也是共享了同一内存。


#原型对象属性
Snail.prototype.attrname = "";

封装

函数是一个工具 对象是一个工具包

继承

1.可以访问父类的属性和方法 2.可以定义自己的一些属性和方法

#方法会使用指定的原型对象及其属性去创建一个新的对象
Object.create(proto[, propertiesObject])
实现组合继承,常用方式
//基类 Person 也是父类
var Person = function() {
    this.name = '张三';
    this.age = 18;
};

//person的原型方法
Person.prototype = {
    say: function() {
       console.log('===');
    }
};

//实现继承Person的属性
var Student = function() {
      //继承父类的核心
      Person.call(this, arguments);
      //实现自己的属性
      this.sID = '000001'
      this.jiemu = '唱歌'
      this.luobenTimes = 0
};

//实现继承Preson的方法
Student.prototype = new Person();

//实现constructor赋值
Student.prototype.constructor =  Student

//实现自己的方法
Student.prototype.com = function() {
     console.log('123');
};

var x = new Student();
x.say(); //===
x.com(); //123
console.log(x.sID) //000001
console.log(x.jiemu) //唱歌

寄生组合式继承
function inheritPrototype(subType, superType) {
  var prototype = Object.create(superType.prototype); //创建对象
  prototype.constructor = subType; //增强对象
  subType.prototype = prototype; //指定对象
}

function SuperType(name) {
  this.name = name,
  this.colors = ["red", "blue", "green"]
}

SuperType.prototype.sayName = function() {
  console.log("3:"+this.name)   //bbb
};

function SubType(name, age) {
  SuperType.call(this, name);
  this.age = age;
}

inheritPrototype(SubType, SuperType);

SubType.prototype.sayAge = function() {
  console.log("5:"+this.age);   //18
};

var person1 = new SubType("bbb", 18);
console.log("1:"+person1.name); //bbb
console.log("2:"+person1.age); //18
console.log("4:"+person1.sayName()); //undefined
console.log("6:"+person1.sayAge()); //undefined  
console.log("7:"+person1.colors); //red,blue,green

多态

一个引用类型(变量)在不同情况下的多种状态。多态是指通过指向父类的引用,来调用在不同子类中实现的方法。

重载

js不支持重载 判断传参个数做相应操作来实现重载

原型链 proto

构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

命名空间

var yw = {
      version: '1.0'
};

yw.common = {};

yw.ui = {};
yw.ui.mobile = {};

yw.page = {};
yw.page.user = {};