OOP
继承、封装、多态、抽象
OOP
继承、封装、多态、抽象
Foo.prototype下面有一个__proto__的属性指向Object.prototype
Foo.prototype下面有一个__proto__的属性指向Object.prototype
Prototype继承的关系
Student.prototype.constructor = Student;//将constructor修正为Student函数 // 否则将指向Person函数
Student.prototype = Object.create(Person.prototype)//Object.create 创建一个空对象,原型指向Person.prototype //如果将Person.prototype直接赋值,那么在为Student.prototype上增加一些方法 //或属性时会影响Person 对象是引用类型值
Student.prototype = Object.create(Person.prototype)//将原型指向Person.prototype的对象赋值给Student.prototype Student构造的实例将继承Student.prototype上的方法及属性,同时继承了Person prototype对象上的方法及属性
如果从链表去理解 那constructor确实不过是链表内部"非指针"的一个属性"而已"
再写一点关于函数.prototype.__proto__ 和 函数.__proto__的问题
话说为什么要有 函数.__proto__ 因为函数也是对象 函数自身除了继承Object.prototype里的方法外 也有一些函数自己需要继承的公共方法 那这个方法写在哪里 总不能写在Object.prototype里吧 那样所有的对象就都有函数的方法了 岂不乱套? 所以 函数.prototype.__proto__ 指向的是Object.prototype 这样函数可以继承对象的共有方法 而函数.__proto 指向函数.prototype对象 则可以继承所有函数应有的共有方法
//(这句待定)所有不在(对象/函数)下的__proto__ 会在其prototype里(如果有prototype的话
对象.__proto__(next指针) 指向另一个对象prototype
函数.__proto__(next指针) 直接指向函数.prototype
继续用C的思想理解JavaScript
这里有Object.create 视频里说过了 是新建一个对象 这个对象有一个___proto__属性 这个属性指向了括号里的对象 再将这个对象赋给"子类"的prototype属性(直接说就是将子类的prototype设置为新创建的对象 这个新创建的对象里面有一个__proto__属性 指向"父类"的prototype)
用c来理解 这里构造了一个节点 节点的next指向父类的prototype对象的首地址 父类的Person.prototype里的__proto__(next)指向谁? Object.prototype 为什么? 因为只有prototype里面有__proto__属性(指针) 其实就是next指针 那这个Object.prototype里的__proto__指向谁(连看都不用看 肯定有__proto__ 就像单链表肯定有next) 指向null呗 因为是最后一个节点 而这个null 和c里的NULL的关系吗.. 嘿嘿
话说typeof null => 'object' <你不知道的JavaScript(上)>第103页 里面说是底层null的二进制值都是0 而在JavaScript中前三位都为0的话会被判定为object类型
而我认为 null就是指针类型 而对象也是指针类型 因为对象就是个指针(也就是地址) c里面的NULL是什么? -> 空指针!!
ok 我又要开始写东西了..
<你不知道的JavaScript(上)>里的第91页 写道:
在用new调用函数是 会自动执行如下操作:
1.创建(构造)一个全新的对象
3.这个新对象会绑定到函数调用的this
4.如果函数没有返回其他对象, 那么new表达式中的函数调用会自动返回这个新对象
开始YY:
"创建一个新的对象" 新的对象有多大? "绑定到函数调用的this" 其实就是把新"new"出的空间首地址赋给this吧 然后返回这个地址 也就是第四条"会自动返回这个新对象"
在<你不知道的JavaScript(上)>的第91页 写的是:
这个新对象会被执行[[Prototype]]连接
我的现在(2020/07/14)的理解是 这个新对象中会添加一个叫"__proto__"的属性 这个属性是一个地址 或者说是一个"指针" 而这个指针的值就是构建他的"类"或者说是"函数"的prototoype属性 而这个prototype是一个对象 也就是说 这个实例化对象的__proto__指针指向了构造他的"类"(虽然JavaScript没有类)的prototype属性(公共) 这个属性是所有构造于这个"类"的实例/对象的共享对象 通过__proto__来进行访问
我TM发现 这竟然是个单链表 这个单链表是一个顺序依次向头部插入的单链表 而单链表的末尾 则是"正常到不过如此"的null.. 而这个null 在C里 是NULL 这的__proto__不就是单链表里的next指针吗?!!
视频里说"prototype 不是'对象的原型' 而是 属性" 也就是说 不要把对象的原型和prototype混淆了
对象的原型 在这里 比如说 就是obj3.__proto__ 只不过 obj3.__proto__是一个地址(我自己的理解) 这个地址指向函数的prototype属性 也就是说: __proto__ 是指针!
prototype 是"对象属性" 这里的意思(我的理解是) prototype是一个属性 他本书是一个对象
OOP概念
实例讲解 。
这一节有点难,回头再来看几遍
Object.create():创建一个空对象并且它的原型指向括号里的参数。
此时右侧:
与Student.prototype.learn=function(){}
就是这个空对象在添加属性,属性值为函数。即:{learn:function(){}}。
而{}.__proto__空对象的原型也即上面所述,指向create里的参数。
obj.__proto__叫做obj的原型,它是构造器的prototype。
复杂概念,
potype属性与原型
基于原型继承
oop编程
面向对象继承
原型的继承,要用 object.create(),避免会修改【被继承】的原型
function Person(name,age){
this.name = name;
this.age = age;//不在Person的prototype对象属性上!!!
}
//当var newPerson=new Person();时,this指向newPerson。同时newPerson可以直接访问Person上的属性和方法,但Person得Peson.prototype.method()访问!!
Person.prototype.hi = function(){
document.write("Hi,my name is "+this.name+".I'm "+this.age+"years old now.");
};
Person.prototype.LEGS_NUM = 2;
Person.prototype.ARMS_NUM = 2;
Person.prototype.walk = function(){
document.write(this.name+"is working.");
};
//以上两个方法和两个属性都是加在Person的prototype上的,为了继承!!!
function Student(name,age,className){
Person.call(this,name,age);//this为Student
this.className = className;
}
Student.prototype = Object.create(Person.prototype);//Object.create创建一个空对象,并且这个对象的原型指向Object.create的参数。
//上面一句不能Student.prototype = Person.prototype;
//不然会导致修改Student.prototype修改时,Person.prototype也改了
//也不能new Person给Student,因为new出来的都是对像,而Student是函数,有自己的参数,可以把Person看为父对象函数,Student为子对象函数
Student.prototype.constructor = Student;//不设置时,consrtuctor会指向Person
Student.prototype.hi = function(){
document.write("Hi,my name is "+this.name+".I'm "+this.age+"years old now,and from "+this.className+".");
};//会覆盖Person.prototype的hi方法(因为之下而上的访问顺序)
Student.prototype.learn = function(subject){
document.write(this.name + " is learning " + subject + " at " +this.className + ".");
};
//test
var bosn =new Student("Bosn",27,"Class 3,Grade 2");
bosn.hi();
bosn.LEGS_NUM;
bosn.walk();
bosn.learn('math');
function Person(name,age){
this.name = name;
this.age = age;//不在Person的prototype对象属性上!!!
}
//当var newPerson=new Person();时,this指向newPerson。同时newPerson可以直接访问Person上的属性和方法,但Person得Peson.prototype.method()访问!!
Person.prototype.hi = function(){
document.write("Hi,my name is "+this.name+".I'm "+this.age+"years old now.");
};
Person.prototype.LEGS_NUM = 2;
Person.prototype.ARMS_NUM = 2;
Person.prototype.walk = function(){
document.write(this.name+"is working.");
};
//以上两个方法和两个属性都是加在Person的prototype上的,为了继承!!!
function Student(name,age,className){
Person.call(this,name,age);//this为Student
this.className = className;
}
Student.prototype = Object.create(Person.prototype);//Object.create创建一个空对象,并且这个对象的原型指向Object.create的参数。
//上面一句不能Student.prototype = Person.prototype;
//不然会导致修改Student.prototype修改时,Person.prototype也改了
Student.prototype.constructor = Student;//不设置时,consrtuctor会指向Person
Student.prototype.hi = function(){
document.write("Hi,my name is "+this.name+".I'm "+this.age+"years old now,and from "+this.className+".");
};//会覆盖Person.prototype的hi方法(因为之下而上的访问顺序)
Student.prototype.learn = function(subject){
document.write(this.name + " is learning " + subject + " at " +this.className + ".");
};
//test
var bosn =new Student("Bosn",27,"Class 3,Grade 2");
bosn.hi();
bosn.LEGS_NUM;
bosn.walk();
bosn.learn('math');
function Person(name,age){
this.name = name;
this.age = age;//不在Person的prototype对象属性上!!!
}
//当var newPerson=new Person();时,this指向newPerson。同时newPerson可以直接访问Person上的属性和方法,但Person得Peson.prototype.method()访问!!
Person.prototype.hi = function(){
document.write("Hi,my name is "+this.name+".I'm "+this.age+"years old now.");
};
Person.prototype.LEGS_NUM = 2;
Person.prototype.ARMS_NUM = 2;
Person.prototype.walk = function(){
document.write(this.name+"is working.");
};
//以上两个方法和两个属性都是加在Person的prototype上的,为了继承!!!
function Student(name,age,className){
Person.call(this,name,age);//this为Student
this.className = className;
}
Student.prototype = Object.create(Person.prototype);//Object.create创建一个空对象,并且这个对象的原型指向Object.create的参数。
//上面一句不能Student.prototype = Person.prototype;
//不然会导致修改Student.prototype修改时,Person.prototype也改了
Student.prototype.constructor = Student;//不设置时,consrtuctor会指向Person
Student.prototype.hi = function(){
document.write("Hi,my name is "+this.name+".I'm "+this.age+"years old now,and from "+this.className+".");
};//会覆盖Person.prototype的hi方法(因为之下而上的访问顺序)
Student.prototype.learn = function(subject){
document.write(this.name + " is learning " + subject + " at " +this.className + ".");
};
//test
var bosn =new Student("Bosn",27,"Class 3,Grade 2");
bosn.hi();
bosn.LEGS_NUM;
bosn.walk();
bosn.learn('math');
使用对象字面量创建原型方法,会重写原型链,要小心!
基于原型的继承