JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)

面向对象编程:

面向:以什么为主,基于什么模式

对象:由键值对组成,可以用来描述事物,存储数据的一种数据格式

编程:使用代码解决需求

面向过程编程:

按照我们分析好的步骤,按步骤解决问题

优点:性能比面向对象高,适合跟硬件联系很紧密的东西

缺点:没有面向对象那么容易维护,复用,扩展

面向对象编程:

把事务分解成一个个对象,然后由对象之间分工与合作,分工明确,每一个对象都是功能中心

面向对象特性:封装性、继承性 、多态性

封装性:将一个功能封装起来,小封装

将多个函数封装起来,整体封装起来形成一个具体的对象

继承性:让一个不具有某些特性的对象,具有另一个对象的特征

多态性:多种形态,一个功能的不同应用场景

应用场景,创建场景

优点:灵活,代码可复用,容易维护和开发适合多人合作大型软件项目,可以设计出低耦合的系统使系统更加灵活、更加易于维护

缺点:性能比面向过程 低

OOP (Object Oriented,OO)面向对象编程

OOA 面向对象分析:需求,拆分成各种各样的小需求,按照分工协作的形式

不断的拆分,直到拆分成每一个步骤可以直接使用分工协作的方式解决

OOD 面向对象设计:高内聚,低耦合

1、创建对象

单体对象

var obj = {};

var obj2 = new object();

多个对象:

人的对象具有自我节介绍的功能

工厂模式:

JS内置的工厂模式:

function CreatPeople(name,age,like){

this.name = name;

this.age = age;

this.like = like;

this.show = function(){

alert("我叫"+this.name+",今年"+this.age+"岁,喜欢"+this.like);

}

}

var obj = new CreatPe

ople("ABC",20,"PHP");

var obj2 = new CreatPeople("QWE",32,"Python");

obj.show();

obj2.show();

JS内置的工厂模式比传统的工厂模式更高效,复用性更强。

JS内置的工厂模式叫构造函数。

new的原理:

1.创建一个新的空对象

2.将这个对象的__proto__和函数的prototype做连接

3.将这个函数中的this改变,指向new新创建的对象

4.检测函数有没有返回对象,没有返回对象,就返回new创建的对象

构造函数,构造自定义的函数,会在函数中使用this、找到被构造出来的对象

隐患:一旦构造函数被直接执行,会错误的产生大量的全局变量

解决隐患:解决不了

自我约束:构造函数不要直接执行

防止误操作:行业习惯:为了防止构造函数被直接执行,产生大量的全局变量,一般将需要被构造的函数的首字母大写

以此标志构造函数和正常函数的区别

function Fn(){

this.name = "root";

}

var f = new Fn()

console.log(f.name)

console.log(name)

this的指向问题

默认绑定:window

隐式绑定:执行对象

显示绑定:函数的方法,强行绑定

new绑定:将函数中的this指向了new出来的对象

【构造函数】

  用来初始化新创建的对象的函数是构造函数。在例子中,Foo()函数是构造函数

【实例对象】

  通过构造函数的new操作创建的对象是实例对象。可以用一个构造函数,构造多个实例对象

function Foo(){};

var f1 = new Foo;

var f2 = new Foo;

console.log(f1 === f2);//false

【原型对象及prototype】

  构造函数有一个prototype属性,指向实例对象的原型对象。通过同一个构造函数实例化的多个对象具有相同的原型对象。经常使用原型对象来实现继承

function Foo(){};

Foo.prototype.a = 1;

var f1 = new Foo;

var f2 = new Foo;

console.log(Foo.prototype.a);//1

console.log(f1.a);//1

console.log(f2.a);//1

【constructor】

  原型对象有一个constructor属性,指向该原型对象对应的构造函数

function Foo(){};

console.log(Foo.prototype.constructor === Foo);//true

由于实例对象可以继承原型对象的属性,所以实例对象也拥有constructor属性,同样指向原型对象对应的构造函数

function Foo(){};

var f1 = new Foo;

console.log(f1.constructor === Foo);//true

proto

  实例对象有一个proto属性,指向该实例对象对应的原型对象

function Foo(){};

var f1 = new Foo;

console.log(f1.__proto__ === Foo.prototype);//true

案例:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>

<style>

body{

width: 100%;

height: 100%;

/* background: url(img/bg.jpg); */

background-color: #000;

}

#container{

width: 100%;

height: 900px;

cursor: pointer;

position: relative;

left: 0;

top: 0;

overflow: hidden;

}

.fire{

width: 30px ;

height: 30px;

position:absolute  ;

bottom: 0;

background: url(img/0.jpg) no-repeat;

border-radius: 50%;

background-size: cover;

}

.small-fire{

width: 100px;

height: 100px;

position: absolute;

border-radius: 50%;

background:url(img/500.gif) no-repeat;

background-size: cover;

}

</style>

</head>

<body>

<div id="container"></div>

</body>

<script src = "../move.js"> </script>

<script src = "../public.js"> </script>

<script>

// OOA:分析

// 烟花,点击出现烟花,运动到鼠标点击处炸开。运动到随机位置,删除

// 实现步骤:

// 1.创建主题烟花。设置样式,和初始位置

// 2.开始运动,从底部上升到鼠标高度。运动结束

// 3.删除主题烟花,创建随机烟花

// 4.立即运动,到终点,删除小烟花

// ood设计

// function Fire(){

//     // 创建主题烟花,设置样式,位置

//     this.init()

// }

// Fire.prototype.init = function(){

//     // 主题烟花,设置样式,和位置

//         2.开始运动,运动结束

//         this.animate()

// }

// Fire.prototype.animate = function(){

//     开始运动,删除主体烟花

//         3.创造小烟花

//         this.createSmall()

// }

// Fire.prototype.createSmall = function (){

//     // 创建小烟花,运动,删掉

// }

// ============================

function Fire (options){             //接受传参

this.x = options.x;          //这里把鼠标点击的横坐标赋值给this的x

this.y = options.y;              //这里把鼠标点击纵坐标赋值给this的y

this.cont = options.parent;      //这里把点击事件的this赋值给了cont

// 运行创建烟花的封装函数

this.init();                     //运行下面创建主体烟花的函数运行

}

Fire.prototype.init = function(){        //创造主体烟花的函数

//主题烟花的新建,样式,位置以及插入的设置

this.ele = document.createElement("div");        //创建一个元素节点,一个div元素并设置名称为ele

this.ele.className = "fire";                     //这里把类名为"fire"的class类赋值给新增加的div元素ele

this.ele.style.left = this.x +"px";              //这里把烟花的定位left设置成鼠标点击x坐标,

this.cont.appendChild(this.ele);                 //这里把新创建的div元素ele插入到cont里面

this.animate();                                  //运行下一步,以回调函数的方式

}

Fire.prototype.animate = function(){                 //创建一个 运动以及小烟花的函数

//开始运动,这里运行运动的封装函数move,(里面包含获取样式的封装函数)

move(this.ele,{                                  //move是之前封装的运动的函数,把插入的div元素和鼠标点击的y坐标赋给了的top,还有删除元素及运行下一个函数的回调函数,传给move,形成一个运动效果

top:this.y

},function(){

//主体烟花出现后,删除这个主体烟花,并创建小烟花

this.ele.remove();

this.createSmall()

}.bind(this))   //这里的bind是找回this

}

Fire.prototype.createSmall = function(){                 //创建小烟花和删除小烟花函数

//创建小烟花,运动,然后删除

var num = random(10,20);    //这里是创建小烟花的个数的随机数

var r = random(100,500)

// console.log(num);

for(var i=0;i<num;i++){                               //循环遍历每一个小烟花,给他设置样式以及位置

let div = document.createElement("div");             //创建新的div

div.className ="small-fire";                         //赋予样式

div.style.left = this.x +"px";                       //设置定位的left为鼠标的x坐标

div.style.top = this.y +"px";                        //设置定位的top为鼠标点击的坐标

div.setAttribute("i",i)   //这里i的作用为给新生成的div一个编号,后期删除的效果会比较好

this.cont.appendChild(div);                  //在cont插入新创建的div

//生成烟花位置的随机数的坐标

// var l = random(0,this.cont.offsetWidth - div.offsetWidth);       //烟花位置的l为从到cont的宽度和高度减去新创建的小烟花的高宽之间的随机数

// var t = random(0,this.cont.offsetHeight - div.offsetHeight);

// console.log(cont);

var l = parseInt(Math.cos(Math.PI/180*(360/num*i))*r)+this.x;

var t = parseInt(Math.sin(Math.PI/180*(360/num*i))*r)+this.y;

move(div,{                                //move,生成运动传入元素div和位置(定位信息)

left:l,

top:t

},function(){

div.remove()                     //随即把插入的div删除

})

}

}

var ocont = document.getElementById("container");            //获取div元素

ocont.onclick = function(eve){                               //设置点击事件,点击div产生事件

var e = eve ||window.event;                          //事件兼容以及获取事件

new Fire({                                           //构造一个面向对象的函数,并传参

x:e.offsetX,                                        //把鼠标点击的横坐标赋值给x

y:e.offsetY,                                 //把鼠标点击的纵坐标赋值给y

parent:this                                  //把点击事件的this赋值给parent

});

}

原文地址:https://www.cnblogs.com/zxlone/p/11518782.html

时间: 2024-10-18 01:38:59

JavaScript中的面向对象编程,详解原型对象及prototype,constructor,proto,内含面向对象编程详细案例(烟花案例)的相关文章

javascript中=、==、===区别详解

javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题,却有着大影响,所以决定深入分析下.1.= 赋值运算符 //例: var n=1; console.log(n);//1 n=n+1; console.log(n);//2 2.== 值比较运算符 值比较运算符在表达式两边的数据类型不一致时,会隐式转换为相同数据类型,然后对值进行比较. //例: var a=

JavaScript中的Date类型详解与moment简介

关于JavaScript中的Date类型,相信JSer们都不会陌生吧,但是也必然为那个复杂难记的各种转换函数所头疼,本文将分享一下我对JS中的Date类型的一些知识小总结,并把其中容易犯错的地方指出来,同时简介和推广moment.js这个js库,希望大家看完文章后以后在对Date类处理如鱼得水. 1 时间的唯一性与多样性 某一时刻在全世界任何地区应该是唯一的,时区的不同是为了让地球不同时区的人的中午十二点都是太阳正上当头,形成交流上没有那么多障碍.而这一标准就是大家熟知的格林威治标准时间(Gre

javascript 中的 this 关键字详解

1.javascript 中 什么是 this? this 指的是当前行为执行的主体,或者是当前方法执行的主体 context:是当前行为或者方法执行的环境 实例: xx 去北京饭店吃东西:上下文是“北京饭店”, this 是 xx 2. 那么如何判断一个函数在执行的时候,函数体内的 this 关键字是谁呢?主要有以下几条规律:  1)一个函数体内的 this 关键字和这个函数的在哪里定义,哪里执行都没有关系;   2) 判断一个方法执行的时候,函数的执行主体是谁?主要看方法前面有没有点(.),

第149天:javascript中this的指向详解

js中的this指向十分重要,了解js中this指向是每一个学习js的人必学的知识点,今天没事,正好总结了js中this的常见用法,喜欢的可以看看: 1.全局作用域或者普通函数中this指向全局对象window. 1 //直接打印 2 console.log(this) //window 3 4 //function声明函数 5 function bar () {console.log(this)} 6 bar() //window 7 8 //function声明函数赋给变量 9 var ba

JavaScript中的Array数组详解

ECMAScript中的数组与其他多数语言中的数组有着相当大的区别,虽然数组都是数据的有序列表,但是与其他语言不同的是,ECMAScript数组的每一项可以保存任何类型的数据.也就是说,可以用数组的第一个位置来保存字符串,第二个位置保存数值,第三个位置保存对象,而且ECMAScript数组的大小是可以动态调整的,即可以随着数据的添加自动增长以容纳新增数据. 数组的创建 创建数组的基本方式有两种,第一种是使用Array构造函数. var arr = new Array(); 如果预先知道数组要保存

JavaScript中的跨域详解(内附源码)

什么是跨域? 什么是跨域? 所谓跨域,就是如果在不同的域名下面存在数据交互,这个时候就会存在跨域的问题,这里要说明的是在同一个网站不同的文件夹下的数据交互是不存在跨域问题的. 哪些情况下存在跨域问题? 主域和子域之间会存在跨域问题(比如 www.a.com 和 www.a.b.com). 不同的域名存在跨域问题,哪怕这两个域名指向的是同一个ip地址. 为什么 ajax 不可以跨域? 因为 ajax 是通过 XMLHttpRequest 这个对象来进行数据之间的交互的,而 XMLHttpReque

JavaScript中数组Array方法详解

ECMAScript 3在Array.prototype中定义了一些很有用的操作数组的函数,这意味着这些函数作为任何数组的方法都是可用的. 1.Array.join()方法 Array.join()方法将数组中所有元素都转化为字符串并连接在一起,返回最后生成的字符串.可以指定一个可选的符号或字符串在生成的字符串中来分隔数组的各个元素.如果不指定分隔符,默认使用逗号.注意:此方法不会改变原始数组 var arr = ['a', 'b', 'c']; console.log(arr.join());

JavaScript中的eval()函数详解

和其他很多解释性语言一样,JavaScript同样可以解释运行由JavaScript源代码组成的字符串,并产生一个值.JavaScript通过全局函数eval()来完成这个工作 eval(“1+2”),-> 3 动态判断源代码中的字符串是一种很强大的语言特性,几乎没有必要在实际中应用.如果你使用了eval(),你应当仔细考虑是否真的需要使用它. 一.eval()是一个函数还是一个运算符 eval()是一个函数,但由于它已经被当成运算符来对待了..JavaScript语言的早期版本定义了eval函

PHP和javascript中url编码解码详解

在实际开发中,我们可能会遇到路径编码解码的问题,下面总结了一下: PHP中: 1.urlencode(编码),urldecode(解码) $a = urlencode('http://www.baidu.com?name=test&query=字母'); echo $a //http%3A%2F%2Fwww.baidu.com%3Fname%3Dtest%26query%3D%E5%AD%97%E6%AF%8D 2.rawurlencode.rawurldecode 这个函数跟上面的大部分一模一