面向过程
对象的创建
在js中,对象的创建有两种方式
- new Object()
- {}
通过上述的两种方式,都可以创建一个空的对象
var obj1 = new Object();
console.log(obj1);
var obj2 = {};
console.log(obj2);
//打印的都是一个空对象
这时,我们通过在一个空的对象上添加特征来扩展我们想要的对象类型
var obj3 = new Object();
obj3.name = "小明";
obj3.gender = "男";
obj3.age = 18;
console.log(obj3);
//打印的就是带着不同属性和值的对象
在实际开发中,我们可能会创建很多相同特征(类型)的对象,那么我们会把创建相同特征的对象的过程进行封装
function creat(name,gender,age){
var obj = new Object();
obj3.name = name;
obj3.gender = gender;
obj3.age = age;
return obj;
}
//在使用时通过传参来创建不同的对象
var obj1 = creat("小明","男",18);
var obj2 = creat("小红","女",28);
new
new是运算符的一种,通过new运算符运算函数,会得到一个对象的结果,new只能和函数配合使用,new只能和函数配合使用,像new Data(),new Object(),new Arr()等等一些常用的都是我们浏览器里的js解析器自带的函数,只是把创建特征过程没有展示出来给我们看到,我们使用的时候相当于调用了这个方法
那当我们通过new的方式去调用执行一个函数的时候
- 在函数内部自动创建一个空的对象
- 把该函数的this指向该对象
- 函数执行完成自动返回该对象
function fn(){
console.log(this);
}
var f1 = fn(); //执行了,打印this这个时候指向window this->window
console.log(f1); //f1是个fn执行后,没有返回值,打印是undefind
var f2 = new fn;
//直接通过new来运算执行函数,可以不加() this-> Object 指向fn内部自动创建的一个空对象
var f3 = new fn();
console.log(f2); //打印的是fn {};
console.log(f3); //打印的是fn {}
//通过new来执行一个函数的时候,如果该函数不需要传入任何参数,我们可以省略(),如果不传入任何参数,()也是可以带的,
当我们通过new的方式去调用执行一个函数的时候,返回:
-
如果没有return,返回内部创建的空对象
-
如果有return
- return的是非对象,返回内部创建的空对象
- return的是对象,返回就是return的对象
function fn2(){ return 1; } var r1 = fn2(); console.log(r1); //1 var r2 = new fn2(); console.log(r2); //内部创建的空对象 ==> this ***** function fn3(){ return {x: 100,y: 200}; } var r3 = fn3(); console.log(fn3); //函数return的对象 var r4 = fn3(); console.log(fn4); //函数return的对象
new构造函数的一些注意事项
构造函数 <-> 类
类: 类型,对具有相同特征的对象的抽象描述
对象: 由类创建出来的具体对象(实例),也称为实例化对象
构造函数: 类中用来创建对象的具体函数,类创建对象的时候调用的初始化函数
function Creat(name,gender,age) {
this.name = name;
this.gender = gender;
this.age = age;
this.fn = funciton(){
cosole.log("我是fn函数")
}
this.fn2 = fn2;
}
function fn2(){
cosole.log("我是fn2函数")
}
var obj1 = new Creat("小明","男",18);
obj1.fn(); //我是fn函数
console.log(obj1); //Object
var obj2 = new Creat("小红","女",28);
obj2.fn(); //我是fn函数
console.log(obj2); //Object
console.log(obj1.fn == obj2.fn) //false
console.log(obj1.fn2 == obj2.fn2) //true
通过Creat构造函数创建出来了下面两个对象,这两个对象都拥有相同的特征,不同的对象相同的特征也会有不同的值,每一个对象都拥有属于自己的特征值,但是有时候,对象的一些特征所拥有的值其实也是一样,那么如果每个对象对这样的相同值的特征也是独立保存一份的话,就会照成资源浪费(内存占用),所以我们需要去优化这个问题。
原型,原型链
原型链.jpg为了使对象共有的特征方法维护和管理,所以有一种专门来管理和维护这些共同特征的方法(手段)
当一个函数被创建的时候,该函数下自动会有一些属性(函数也是对象),其中有一个属性,名称:prototype,他的值是一个对象,我们通常就把构造函数创建的对象所拥有的共同特征保存在这些对象的构造函数的prototype属性下,\
当一个对象被创建的时候,对象自动会创建一个属性,名称:proto,该属性也是一个对象,其实该属性就是该对象的构造函数的prototype
当我们去调用一个对象下的属性或方法的时候,对象首先会在自身上查找是否该属性或方法,如果有则调用,如果没有,则会查找自己的proto属性上是否有给属性或方法
总结:
- 我们通常把对象私有属性或方法放置在每个对象自身上
- 我们通常把对象公有(共有)的属性或方法放置在这些对象的构造函数的原型下
function Creat(name,gender,age) {
this.name = name;
this.gender = gender;
this.age = age;
this.fn = funciton(){
cosole.log("我是fn函数")
}
}
Creat.prototype.fn2 = funciton(){
cosole.log("我是fn2函数")
}
var obj1 = new Creat("小明","男",18)
//obj1的__proto__ 其实就是 Creat.prototype
console.log(obj1.__proto__ == Creat.prototype); //true
obj1.fn(); //自己有,直接调用
obj1.fn2(); //自己没有,去看下自己下面的__proto__
var obj2 = new Creat("小红","女",28);
console.log(obj1.fn == obj2.fn); //false
console.log(obj1.fn2 == obj2.fn2); //true
*/这样没创建一个新的对象时,就不用在给每个添加一个单独的fn属性,只用在构造函数下的prototype下添加可以共用的函数,在它下面调用
面向对象例子
拖拽:
<div id="div1"></div>
<style>
#div {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
}
</style>
var div1 = document.querySelector("#div1");
function Drag(elment){
this.elment = elment;
this.disX = 0;
this.disY = 0;
var _this = this; //记录this指向是Drop
this.elment.onmousedown = function(e){
_this.down(e);
//这里如果是this的话,就是找的执行mousedown这个元素了,它下面没有down这个对象,所以上面要记录下_this
document.onmousemove = function(e){
_this.move(e)
}
document.onmouseup = function(){
_this.end();
}
}
}
Drag.prototype.down = function(e){ //传执行时的event
console.log(this)
this.disX = e.clientX - this.elment.offsetLeft; //this => Drop
this.disX = e.clientX - this.elment.offsetLeft;
}
Drag.prototype.move = function(e){
this.elment.style.left = e.clientX - this.disX + 'px';
this.elment.style.top = e.clientY - this.disY + 'px';
}
Drag.prototype.end = function(e){
document.onmousemove = document.onmouseup = null;
}
new Drag(div1); //调用记得加new
网友评论