构造函数,实例对象和原型对象
创建对象的练习
<script>
//对象:人
let person={};
//描述对象
//静态属性
person.name="张三";
person.age=48;
person.sex="男";
person.height=160;
//动态方法
person.say=function(){
console.log("可以说话")
}
person.running=function(){
console.log("可以跑步")
}
//调用对象
//person.say()
/*
描述购物车
init()初始化的函数,如果需要获取元素的时候 元素需要绑定时间的时候,也会在这里绑定
*/
let car={
date:[{},{},{}],
title:["Your Item(s)", "Quantity", "..."],
ele:"页面中存在的元素",
init:function(){
jianshao.οnclick=reduce;
shanchu.οnclick=del;
ele.innerHTML=renderContent;
},
renderTitle:function(){},
renderContent:function(){},
add:function(){},
reduce:function(){},
del:function(){},
total:function(){},
};
car.init();
</script>
工厂函数创建对象
// let s1 = {
// name: "张三",
// age: 18,
// className: "GZ2101",
// };
// let s2 = {
// name: "李四",
// age: 18,
// className: "GZ2101",
// };
// let s3 = {
// name: "王五",
// age: 18,
// className: "GZ2101",
// };
// 工厂函数创建对象
// 定义一个函数 这个函数的返回值为一个对象
// 一般情况 是需要大批量创建 同一类型的对象的时候会使用工厂函数
// 缺点:不知道这个对象的来源
function createStu(name, age) {
return {
// name: name,
// age: age,
name,
age,
className: "GZ2101",
};
}
let s1 = createStu("张三", 18);
console.log(s1);
let s2 = createStu("李四", 20);
console.log(s2);
let s3 = createStu("kk", 2);
console.log(s3);
自定义构造函数创建对象
/*
构造函数的注意点:
【1】函数的首字母为大写(不是规定,而是一个规范)
【2】构造函数的调用,必须使用new关键字调用。当调用构造函数不使用new关键字的时候,那函数就是一个普通的函数
【3】当使用new关键字调用函数的时候,有参数的时候,参数写在调用的括号中,如果不需要传递参数的时候,可以不写()
【4】构造函数的返回值:
1.构造函数中不需要写return 那么就会默认返回this,this指向为这个构造函数的实例对象
2.如果在函数中写了return,但是return后面为基本数据类型,那么函数还是返回this,不返回return后面的值
3.如果return后面的值为一个复杂数据类型,那么这个函数就返回return后面的值
4.一般情况下,是不需要写return
*/
function CreateStu(name,age) {
console.log(this); //CreateStu{}
// return {name:'aaa'};
// this 是实例对象this = {}
this.name = name;
this.age = age;
this.say = function(){
console.log(this.name +'在说话');
}
console.log(this);//CreateStu {name: "张三", age: 18, say: ƒ}
}
// CreateStu();
let res = new CreateStu('张三',18);
// console.log(res);
// res.say();
原型对象
- 当编写构造函数的时候 属性一般写在实例对象上,方法写在原型原型对象上
- Person的原型对象 == Person.prototype
【1】原型对象:每一个函数都有的一个属性,这个属性为prototype。这个属性的属性值是一个对象 Person.prototype={ },这个原型对象上面的属性可以被这个函数new出来的实例对象去调用
【2】__ proto __ 每一个对象都有的属性,对象.__ proto__==实例化这个对象的构造函数.prototype
【3】constructor 是每一个原型对象都存在的一个属性,这个constructor的值为一个函数 指向这个原型对象的构造函数
// Person.prototype.constructor == Person 返回值为true
// console.log(Person.prototype.constructor == Person);
<script>
function Person(name, age) {
this.name = name;
this.age = age;
// this.say = function () {
// console.log(this.name + "可以说话");
// };
// this.info = function () {
// console.log(`大家好,我是${this.name},今年${this.age}`);
// };
}
// 给Person的原型对象 添加 方法
Person.prototype.say = function () {
console.log(this.name + "可以说话");
};
Person.prototype.info = function () {
console.log(`大家好,我是${this.name},今年${this.age}`);
};
// 当编写构造函数的时候 属性一般写在实例对象上,方法写在原型原型对象上
// Person的原型对象 == Person.prototype
// 【1】原型对象:每一个函数都有的一个属性,这个属性为prototype
// 这个属性的属性值 是一个对象 Person.prototype = {}
// 这个原型对象上面的属性 可以被 这个函数new出来的实例对象去调用
// 【2】__proto__ 每一个对象都有的属性
// 对象.__proto__ == 是实例化这个是对象的构造函数.prototype
// 【3】constructor 是每一个 原型对象都存在的一个属性
// 这个constructor 的值为一个函数 指向这个原型对象的构造函数
// Person.prototype.constructor == Person 返回值为true
// console.log(Person.prototype.constructor == Person);
// p 和p1 是Person的实例对象
let p = new Person("老田", 39);
let p1 = new Person("老谢", 49);
// 当普通函数调用的时候 函数中this指向 . 前面的对象
// console.log(p, p1);
// p.__proto__.say(); say() 函数中的this 指向 p.__proto__
// p.say(); say() 函数中this指向 p对象
// console.log(p.__proto__ == Person.prototype);
</script>
面向对象实现拖拽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.box {
width: 100px;
height: 100px;
position: absolute;
left: 0px;
top: 0px;
cursor: move;
background: pink;
}
.box1 {
width: 100px;
height: 100px;
background: green;
position: absolute;
top: 100px;
left: 0px;
cursor: move;
}
</style>
</head>
<body>
<div class="box"></div>
<div class="box1"></div>
<script>
/*
创建对象
描述对象
静态属性
ele:拖拽的对象(dom元素)
left:移动的left
top:移动的top值
动态方法
init() 初始化,获取元素 绑定事件
move()
使用对象
*/
function Drag(ele) {
this.ele = ele;
this.left = this.ele.offsetLeft;
this.top = this.ele.offsetTop;
// 把初始化的函数调用
this.init();
}
Drag.prototype.init = function () {
// console.log(this);
this.ele.onmousedown = () => {
// 因为 这个函数是事件调用 所这个函数中this 指向是绑定事件的这个元素 没有办法 调用move函数
console.log(this);
this.move();
};
document.onmouseup = function () {
document.onmousemove = null;
};
};
Drag.prototype.move = function () {
document.onmousemove = () => {
let e = window.event;
this.left = e.clientX - this.ele.offsetWidth / 2;
this.top = e.clientY - this.ele.offsetHeight / 2;
this.ele.style.left = this.left + "px";
this.ele.style.top = this.top + "px";
};
};
let box = document.querySelector(".box");
let box1 = document.querySelector(".box1");
// new Drag(box);
new Drag(box1);
</script>
</body>
</html>
弹幕案例
-
创建对象:确定对象==>弹幕的文字
-
描述对象
【1】静态属性
文字的大小 fontSize
文字的颜色color
文字的位置top
文字的移动速度speed
文字的内容text
父元素(页面中存在的元素)ele
【2】动态方法
初始化 init()
移动事件 move()
当元素移动到最左边的时候移除元素 remove()
随机数 函数randomNum()
随机颜色 randomColor() -
使用对象
点击发送的时候调用弹幕这个对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.container {
width: 800px;
margin: 0 auto;
padding-bottom: 10px;
background-color: #dfdfdf;
}
#barrage {
position: relative;
height: 500px;
margin-bottom: 10px;
background-color: #000;
overflow: hidden;
}
#barrage .bar-item {
position: absolute;
left: 100%;
white-space: nowrap;
}
#msg {
margin-left: 10px;
width: 400px;
height: 30px;
border: 1px solid #999;
border-right: none;
box-sizing: border-box;
vertical-align: middle;
}
#msg + button {
padding: 0 10px;
height: 30px;
vertical-align: middle;
}
</style>
</head>
<body>
<div class="container">
<div id="barrage"></div>
<input type="text" id="msg" />
<button id="btn">发送</button>
</div>
<script>
funtion Barrage(ele,text){
this.ele=ele;
this.text=text;
this.fontSize=this.randomNum(12,30);
this.color=this.randomColor();
this.top=this.randomNum(0,this.ele.offsetHeight-this.ele.fontSize);
this.speed=this.randomNum(20,100);
this.init();
}
//初始化函数
Barrage.prototype.init=function(){
//创建弹幕元素 把span元素添加到实例对象上 其他函数都可以通过this使用
this.span=document.createElement("span");
this.span.classList.add("bar-item");
this.span.style.top=this.top+"px";
this.span.style.fontSize=this.fontSize+"px";
this.span.innerHTML=this.text;
this.ele.appendChild(this.span);
//当元素添加到页面之后需要调用this.move()
this.move();
};
Barrage.prototype.move()=function(){
let timer=setInterval(()=>{
let left=parseInt(this.getStyle(this.span,"left"))-10;
this.span.style.left=left+"px";
//停止定时器
if(left<=-this.span.offsetWidth){
clearInterval(timer);
this.span.remove();
}
},this.speed)
}
Barrage.prototype.randomNum = function (min, max) {
if (min > max) {
return parseInt(Math.random() * (min - max + 1) + max);
}
return parseInt(Math.random() * (max - min + 1) + min);
};
Barrage.prototype.randomColor = function () {
return `rgb(${this.randomNum(0, 255)},${this.randomNum(
0,
255
)},${this.randomNum(0, 255)})`;
};
Barrage.prototype.getStyle = function (ele, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(ele)[attr];
}
return ele.currentStyle[attr];
};
let btn = document.querySelector("#btn");
let barrage = document.querySelector("#barrage");
let msg = document.querySelector("#msg");
btn.onclick = function () {
if(!msg.value){
alert('请输入内容')
return
}
new Barrage(barrage, msg.value);
msg.value = '';
};
</script>
</body>
原型链
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
// 原型链:对象访问属性的机制
// 就近原则访问: 先在自己本身查找属性,如果有就使用,没有就去上一层原型对象查找,找到就使用,没有找到就继续往上查找,直到查找到 Object构造函数的原型对象还没有找到就会返回undefined
// let obj = {};
// let obj = new Object()
// console.log(obj);
// console.log(obj.name);
// console.log(obj.__proto__ == Object.prototype);
// console.log(obj.toString);
function Person() {
this.name = "aaa";
}
Person.prototype.age = 18;
Person.name = "123";
// p为 Person 的实例对象
let p = new Person();
/*
原型对象 也是一个对象,那么也是由构造函数实例化出来
原型对象 就是 Object构造函数实例化出来
原型对象.__proto__ == Object.prototype
Object.prototype 也是由Object构造函数实例化出来
但是 Object.prototype.__proto__ == null
Object的原型对象是最顶层的原型对象
*/
console.log(p.name);
console.log(p.age);
console.log(p.toString);
console.log(p.aa);
console.log(p);
</script>
</body>
</html>