对于原型的一知半解
什么是原型对象
* 在JavaScript中 每定义一个对象(函数也是对象)的时候对象都会含有一些预定的属性,其中每一个函数对象都有一个prototype,这个属性指向函数的原型对象。
定理:每个对象都有一个__proto__,但还是函数对象才会有prototype属性;
原型是一个对象,他是对象的实例,用于保存共享的属性和方法
代码示例
function Person() {}
// 虽然写在注释里,但是你要注意:
// prototype是函数才会有的属性
Person.prototype.name = 'Kevin';
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) // Kevin
console.log(person2.name) // Kevin
使用原型实现继承和方法
function A() {
this.a = "a";
}
// console.log(A.prototype);
A.prototype = {
// 修改原型 修正constructor指针的指向
constructor: A,
PI: 3.14
};
var a = new A();
console.log(a.PI);
Proto
-
这个属性其实不是属于构造函数的原型,而是源自object.prototype。
-
上面的构造函数可以通过prototype指向原型,那实例化对象通过就通过__proto__指向原型
function Person() {}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true
- 当读取实例属性的时候,如果找不到就会去继承原型(爸爸)中的属性,如果还是找不到?那就去找再上一级的原型(爸爸的爸爸)一直找到最顶层为止。
继承
- 从其他对象获得属性和方法,
- 对象是如何查找属性的?
- 先是在自身对象中查找,找到则返回
- 沿原型链向上查找,找到则返回
- 知道object.prototype.__proto__都没有找到 就会返回undefined
- 而且继承这个概念来自面向对象编程,JS没有类 但是可以实现面向对象编程思想。并且JS中的Class是构造函数的语法糖。。。。。
通过构造函数继承的实例
//通过构造函数继承。。。。。。
function Father() {
this.say = 'hi';
this.fn = function() {
console.log(this.say);
}
}
// 如何让子类继承父类的属性和方法?
// 修改父类的执行环境
function Son() {
this.name = 'son';
this.f = Father;
this.f();
delete this.f;
this.play = function() {
console.log('玩耍');
}
}
// var f = new Father();
var s = new Son();
console.log(s)
通过原型继承
// 通过原型继承
function A() {
this.a = "a";
this.fn = function() {
return this.a;
}
}
// 让B的实例拥有A的属性和方法
// 将A的实例作为B的原型
function B() {
this.a = 'b';
}
// var a = new A();
// console.log(a);
B.prototype = new A();
B.prototype.constructor = B;
var b = new B();
console.log(b);
</script>
从别的对象上获得属性和方法
var obj = {
x: 1,
fn: function(a, b) {
return a + b + this.x;
}
}
// console.log(obj.fn(3, 5)); //9
// this 在函数中 谁调用该函数 this就指向谁
// 函数是引用类型 引用类型的对象赋值 赋值的是地址
// var fn = obj.fn; //var fn 相当于 window.fn
// // console.log(fn === obj.fn);
// console.log(fn(3, 5)); //NaN window下没有x
// this.x undefined
// 3+5+undefined
var obj2 = {
x: 3
};
// var fn = obj.fn.bind(obj2); //修改this的指向,并绑定参数,返回一个新函数
// console.log(fn(3, 5));
// call apply 和bind有什么区别
// call和apply是立即执行函数 bind是返回新函数
console.log(obj.fn.call(obj2, 2, 5));
console.log(obj.fn.apply(obj2, [2, 5]));
混合继承
// 从父类继承实例属性和方法
// 通过原型继承父类的公共属性或方法
function Father() {
this.say = 'hi';
this.fn = function() {
console.log(this.say);
}
}
Father.prototype.eat = function() {
console.log('吃饭');
}
function Son() {
// 改变父类的执行环境
Father.call(this);
this.name = 'son';
}
Son.prototype = new Father(); // 将父类的实例作为子类的原型
var s = new Son();
console.log(s);
。。。。。。。未完待补充