目录
回顾面向对象的概念
认识面向对象
构造函数
工厂模式
prototype 原型对象
混合法——构造函数
原型详解
继承和多态
继承
多态
ECMA6-class语法
面向对象实战和this指向问题
拖拽继承版和选项卡改造
继承拖拽——实现限制出界
选项卡——面向对象改造
见 认识对象内容
- 原料
- 加工
- 出厂
【注】凡是满足上述三个步骤创建对象的函数,我们把它叫做工厂方法
function createPerson(name, sex){
//1、声明空对象
var obj = new Object();
//2、加工
obj.name = name;
obj.sex = sex;
obj.showName = function(){
alert("我的名字叫" + this.name);
}
obj.showSex = function(){
alert("我的性别是:" + this.sex)
}
//3、出厂
return obj;
}
var p1 = createPerson("blue", "男");
p1.showName();
p1.showSex();
var p2 = createPerson("red","女");
p2.showName();
p2.showSex();
如果我们某一个函数,使用new运算符去调用:
1、当前函数中的this指向新创建的对象
2、自动去完成1.原料和3.出场操作
这种通过new调用函数,我们把它叫做构造函数,构造函数可以构造对象
【注】构造函数一般情况下首字母大写
function Person(name, sex){
this.name = name;
this.sex = sex;
this.showName = function(){
alert("我的名字叫" + this.name);
}
this.showSex = function(){
alert("我的性别是:" + this.sex)
}
}
var p1 = new Person("blue", "男");
p1.showName();
p1.showSex();
var p2 = new Person("red","女");
p2.showName();
p2.showSex();
alert(p1.showName === p2.showName); //false
概念:每一个函数上,都有一个原型对象prototype
/* 想要给数组添加一个方法,可以对数组中每一个元素进行求和 */
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [1, 2, 3, 4, 5];
arr1.sum = function(){
var res = 0;
for(var i = 0; i < this.length; i++){
res += this[i];
}
return res;
}
arr2.sum = function(){
var res = 0;
for(var i = 0; i < this.length; i++){
res += this[i];
}
return res;
}
alert(arr1.sum());
alert(arr2.sum());
alert(arr1.sum == arr2.sum);//false;arr1.sum和arr2.sum是两个函数,尽管他们的代码相同
用在构造函数上,我们可以给构造函数的原型prototype添加方法:
1、如果我们将方法添加到构造函数的原型prototype对象上
2、构造函数构造出来的对象共享原型上所有的方法
var arr1 = [10, 20, 30, 40, 50];
var arr2 = [1, 2, 3, 4, 5];
Array.prototype.sum = function(){
var res = 0;
for(var i = 0; i < this.length; i++){
res += this[i];
}
return res;
}
alert(arr1.sum());
alert(arr2.sum());
alert(arr1.sum == arr2.sum);//true
function Person(name, sex){
this.name = name;
this.sex = sex;
}
//Person构造函数添加方法,添加在构造函数的原型上prototype
Person.prototype.showName = function(){
alert("我的名字叫" + this.name);
}
Person.prototype.showSex = function(){
alert("我的性别是:" + this.sex)
}
var p1 = new Person("blue", "男");
p1.showName();
p1.showSex();
var p2 = new Person("red","女");
p2.showName();
p2.showSex();
alert(p1.showName === p2.showName); //true
构造函数构造出来的对象,有一个属性 __proto__ ,指向构造出这个对象的构造函数的原型
instanceof 关键字
功能:判断某一个对象是否是这个构造函数构造出来的
function Dog({name, type, age}){
//添加属性
this.name = name;
this.type = type;
this.age = age;
}
/* 通过构造函数的原型添加方法 */
Dog.prototype = {
run: function(){
alert(this.name + "会飞快的奔跑");
},
showSelf: function(){
alert(`这是一个${this.type}的,${this.age}岁的,叫${this.name}的小狗`)
}
}
var xiaobai = new Dog({
name: "小白",
type: "比熊",
age: 3
});
alert(xiaobai.__proto__ == Dog.prototype);//true
alert(xiaobai instanceof Dog); //true
alert(xiaobai instanceof Object); //true
var xiaohei = new Dog({
name: "小黑",
type: "拉布拉多",
age: 5
});
alert(xiaohei.__proto__ == Dog.prototype);//true
面向对象,继承,封装(封装构造函数过程),多态
分类更加细分的构造函数
原型链继承
function Dog({name, type, age}){
//添加属性
this.name = name;
this.type = type;
this.age = age;
}
/* 通过构造函数的原型添加方法 */
Dog.prototype = {
run: function(){
alert(this.name + "会飞快的奔跑");
},
showSelf: function(){
alert(`这是一个${this.type}的,${this.age}岁的,叫${this.name}的小狗`)
}
}
function Teddy({name, type, age, color}){
//1、继承父一级构造函数所有的属性
//构造函数的伪装
Dog.call(this,{
name: name,
type: type,
age: age
})
//添加自己的属性
this.color = color;
}
var xiaohong = new Teddy({
name: "小花",
type: '泰迪',
age: 10,
color: "红色"
})
alert(xiaohong.name);
alert(xiaohong.type);
只会在子一级生效,并不会影响父一级构造函数的方法。
继承和多态是同一件事情的两种完全不同的侧重:
继承:侧重是从父一级构造函数,继承到的属性和方法(和父亲一样的地方)
多态:侧重是,子一级,自己重写和新增的属性和方法(和父亲不一样的地方)
面向对象是一个编程思想,支撑面向对象编程思想的语法是类(ECCMA6之前没有类这个概念)和对象,构造函数充当类的角色。
构造函数和对象实现面向对象程序的时候,体现出多态
function Person(name, sex, age){
this.name = name;
this.sex = sex;
this.age = age;
}
Person.prototype.showSelf = function(){
alert(`我是一个叫${this.name},今年${this.age}岁的${this.sex}孩`);
}
//白领人
function Worker(name, sex, age, job){
//1、构造函数的伪装 —— 继承父级的属性
Person.call(this, name, sex, age);
this.job = job;
}
//2、原型链 继承父一级的方法
//<1>通过for...in遍历继承
/* for(var funcName in Person.prototype){
Worker.prototype[funcName] = Person.prototype[funcName];
} */
//<2>Object.create( )
/* Worker.prototype = Object.create(Person.prototype); */
//<3>调用构造函数继承
Worker.prototype = new Person();
Worker.prototype.showJob = function(){
alert("我的工作是:" + this.job);
}
var w1 = new Worker("小米","男",20,"程序员");
w1.showSelf();
w1.showJob();
-----------------------------------------------------------------------------------------
/* ECMA6 class语法 */
class Person{
//class属性添加
constructor(name, sex, age){
this.name = name;
this.sex = sex;
this.age = age;
}
showSelf(){
alert(`我是一个叫${this.name}的,今年${this.age}岁的${this.sex}孩`);
}
}
var p1 = new Person("blue","男",18);
p1.showSelf();
//extends 继承
class Worker extends Person{
constructor(name, sex, age, job){
//1、继承到父一级的属性
super(name, sex, age);
this.job = job;
}
showJob(){
alert("我的工作是" + this.job);
}
}
var w1 = new Worker("小米","男",20,"程序员");
w1.showSelf();
w1.showJob();
/*
this指向当前函数的主人。
总结this容易混乱的部分:
1、事件绑定
2、定时器
*/
function Aaa(){
this.a = 10;
var oBtn = document.getElementById("btn1");
var _this = this;
// //赋值
// oBtn.onclick = function(){
// _this.show();
// }
// oBtn.onclick = this.show.bind(this);
//传参 等于 赋值
// setTimeout(this.show.bind(this),4000);
setTimeout(function(){
_this.show();
},4000);
}
Aaa.prototype.show = function(){
alert(this.a);
}
window.onload = function(){
var a1 = new Aaa();
a1.show();
}
// var oDiv = null;
// var offsetX = 0;
// var offsetY = 0;
function Drag(id){
this.oDiv = document.getElementById(id);
var _this = this;
this.oDiv.onmousedown = function(ev){
_this.funcDown(ev);
};
document.onmouseup = this.funcUp;
}
Drag.prototype.funcDown = function(ev){
var e = ev || window.event;
this.offsetX = e.clientX - this.oDiv.offsetLeft;
this.offsetY = e.clientY - this.oDiv.offsetTop;
var _this = this;
document.onmousemove = function(ev){
_this.funcMove(ev);
};
}
Drag.prototype.funcMove = function(ev){
var e = ev || window.event;
this.oDiv.style.left = e.clientX - this.offsetX + 'px';
this.oDiv.style.top = e.clientY - this.offsetY + 'px';
}
Drag.prototype.funcUp = function(){
document.onmousemove = null;
}
window.onload = function(){
new Drag("div1");
}
可以将上述函数封装在.js中,调用的时候会非常方便
function Drag(id){
this.oDiv = document.getElementById(id);
var _this = this;
this.oDiv.onmousedown = function(ev){
_this.funcDown(ev);
};
document.onmouseup = this.funcUp;
}
Drag.prototype.funcDown = function(ev){
var e = ev || window.event;
this.offsetX = e.clientX - this.oDiv.offsetLeft;
this.offsetY = e.clientY - this.oDiv.offsetTop;
var _this = this;
document.onmousemove = function(ev){
_this.funcMove(ev);
};
}
Drag.prototype.funcMove = function(ev){
var e = ev || window.event;
this.oDiv.style.left = e.clientX - this.offsetX + 'px';
this.oDiv.style.top = e.clientY - this.offsetY + 'px';
}
Drag.prototype.funcUp = function(){
document.onmousemove = null;
}
/*
限制出界的拖拽,要拥有拖拽原有的所有功能
*/
function LimitDrag(id){
//继承父一级所有的属性 构造函数的伪装
Drag.apply(this, [id]);
}
//继承方法 原型链
for(var funcName in Drag.prototype){
LimitDrag.prototype[funcName] = Drag.prototype[funcName];
}
LimitDrag.prototype.funcMove = function (ev){
var e = ev || window.event;
var l = e.clientX - this.offsetX;
var windowWidth = document.documentElement.clientWidth || document.body.clientWidth;
if(l <= 0){
l = 0;
}
if(l >= windowWidth - this.oDiv.offsetWidth){
l = windowWidth - this.oDiv.offsetWidth;
}
var t = e.clientY - this.offsetY;
var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
if(t <= 0){
t = 0;
}
if(t >= windowHeight - this.oDiv.offsetHeight){
t = windowHeight - this.oDiv.offsetHeight;
}
this.oDiv.style.left = l + 'px';
this.oDiv.style.top = t + 'px';
}
Document
Document
HTML5是Web中核心语言HTML的规范,用户使用任何手段进行网页浏览时看到的内容原本都是HTML格式的。在浏览器中通过一些技术处理将其转换成了课识别的信息。HTML5在从前HTML4.01的基础上进行了一定的改进,虽然技术人员再开发过程中可能不会将这些新技术投入应用,但是对于该种技术的新特性网站开发技术人员是必须要有所了解的。
Python是一种计算机程序设计语言。是一种面向对象的动态类型语言,最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越来越多被用于独立的、大型项目的开发。
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念。因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好的实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程