一、对象
- 对象(object)是某一个类(class)的实例(instance)
- 类可以理解成模具
- 对象可以理解成模具开发的产品
- 对象的另一个特性就是封装:把细节隐藏掉,想要修改对象的属性需要通过它提供的方法去访问
//用一个构造函数Fn生成了一个对象p; 对象p继承自构造函数Fn()
function Fn(){
console.log('name:Ceaser');
}
//通过类Fn(),生成属于这个类型的对象p
//一个函数通过new操作符,可以让一个函数作为构造函数生成一个对象
var p = new Fn();
typeof p; //object
//所以这个对象p就是这个类的实例
p instanceof Fn; //true p是Fn的实例
//p1和p2作为两个不同的新实例(创建了不同的副本),对类(属性的值)做修改互不影响
function Fn(){
this.name = 'hunger';
this.age = 18;
}
var p1 = new Fn();
var p2 = new Fn();
p1.name = 'velley';
console.log(p2); //hunger
//根据参数需要把参数设置为变量
function Fn(name, age){
this.name = name;
this.age = age;
}
var p1 = new Fn('hunger', 21);
var p2 = new Fn('velley', 14);
//调用对象的方法
function Fn(name, age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name + '说: 我' + this.age + '岁了。');
}
}
var p1 = new Fn('hunger', 21);
var p2 = new Fn('velley', 14);
p1.say(); //hunger说: 我21岁了。
p2.say(); //velley说: 我14岁了。
//注意:不使用new,p1为undefined 28.24-31.05
function Fn(name, age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name + '说: 我' + this.age + '岁了。');
}
}
var p1 = Fn('hunger', 21);
var p2 = new Fn('velley', 14);
console.log(p1); //undefined
二、原型
- 构造函数Person中存在属性prototype,属性prototype指向原型对象Prototype
原型对象Propotype包括:构造器constructor(指向构造函数Person) 和 原型属性_ proto_ 以及 自己定义的方法或属性,
当通过new方法创建构造函数Person的实例后得到对象p1,实例的_ proto_指向它的创造者Person的整个原型Propotype
此时对象p1包括:name:hunger、age:21、以及继承自p1的原型属性_ proto_
function Person(name, age){
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name + '说: 我' + this.age + '岁了。');
}
}
var p1 = new Person('hunger', 21);
- 原型对象是对象实例的公共空间。
可以通过对象实例访问保存再原型对象中的值,但不能通过对象实例重写原型中的值
function Person(name, age) {
this.name = name;
this.age = age;
this.say = function () {
console.log(this.name + '说: 我' + this.age + '岁了。');
}
}
Person.prototype = {
friend: 'Cherry'
}
var p1 = new Person('hunger', 21);
p1.friend = 'Neco';
console.log(p1.friend); //Neco
var p2 = new Person('Danee', 22);
console.log(p2.friend); //Cherry
Person对象的_proto_ 与 Prototype原型对象的_proto_ 指向Object对象
原型
三、原型链
-
对象实例p1访问属性时先从继承来的在构造函数Person的属性中查找,查找不到时再从构造函数Person的原型对象Prototype中查找
原型链 - 调用
p2.name
,对象实例p2没有name属性,此时要从原型上查找。得到hello
原型链 - 深入:
_ proto_指向构造它的函数的原型对象,prototype指向它自身的函数的原型对象
任何对象都是被创建出来的,对象内部都存在原型属性_proto_,_proto_保存着构造它的原型对象
对象Person里面有属性prototype,证明Person本身是一个对象(函数也是一种对象),所以对象Person内部也存在原型属性_proto_
原型对象Prototype也存在属性_proto_
Object在JS中本身是一个函数function(){ [native code] }
,new Object
才是创建一个对象Object{}
任何对象都是由Object函数创建的(即new Object方式)
Object.prototype === Person.prototype._proto_
返回true
证明原型对象Prototype的创建者是Object。因为原型对象Prototype的原型属性_ proto_指向Object的原型对象Prototype
由此证明:原型对象Prototype的创建者是构造函数Object
function Person(name) {
this.name = name;
}
Person.prototype = {
sayName: function(){
console.log('My name is: ' + this.name);
}
}
var p1 = new Person('hunger');
var p2 = new Person('danee');
p1.sayName();
image.png
原型对象只有一个 [[prototype]] 正常的是隐藏的 访问不到,浏览器为了让你访问到,弄了个__proto__属性
任何一个函数都拥有prototype,任何一个对象都拥有_ proto_
函数中的prototype是创建时就有的
对象中的_ proto_是对象的创造者(即构造函数中的prototype)
因为对象都是由Object函数创建的,所以对象的属性_ proto_指向函数的prototype
上例:
Person.prototype.__proto__ === Object.prototype
p1.__proto__ === Person.prototype
image.png
image.png
原型链
四、基本包装类型
var str = 'hellow';
等同于
var str = new String('hellow');
基本包装类型
image.png
四、继承
function Cake(name, size){
console.log(this);
this.name = name;
this.size = size;
}
Cake.prototype.sayName = function(){
console.log('I am :' + this.name);
}
Cake.prototype.saySize = function(){
console.log('My size is' + this.size);
}
//在函数MilkCake的作用域里执行Cake函数(此时MilkCake取得了Cake的属性)
function MilkCake(name, size, taste){
console.log(this);
Cake.apply(this, [name, size]);
this.taste = taste;
}
//创建一个Cake的对象实例指向 MilkCake的原型对象(此时MilkCake继承了Cake的属性及原型对象)
MilkCake.prototype = new Cake();
//将MilkCake原型对象的构造器指向MilkCake函数
MilkCake.prototype.constructor = MilkCake;
var Cake1 = new MilkCake('牛奶蛋糕', 16, '甜');
console.log(Cake1);
constructor
返回创建实例对象的构造函数的引用,所有对象都会从它的原型对象上继承一个constructor属性
image.png
- 继承原型函数方法(Es5简便方法)
function inherit(superType, subType){
//拷贝一份父函数的原型对象
var _prototype = Object.create(superType.prototype);
//将拷贝原型对象的构造器指向子函数
_prototype.constructor = subType;
//将拷贝的原型对象指向子函数的prototype属性
subType.prototype = _prototype;
}
inherit(superType, subType);
image.png
网友评论