JavaScript基础(3)-JS中的面向对象、定时器、BOM、位置信息
一、创建对象的几种常用方式、
1、使用Object或对象字面量创建对象;
a、使用Object()内置的构造函数来创建对象,例如:
var student = new Object(); // 创建一个student对象 student.name = "easy"; // 属性name student.age = 20; // 属性age
b、字面量方式,例如:
var student = { name : "easy", age : 20 };
2、工厂模式创建对象;
JS中没有类的概念,那么我们不妨就使用一种函数将以上对象创建过程封装起来以便于重复调用,同时可以给出特定接口来初始化对象,例如:
function createStudent(name, age){ var obj = new Object(); obj.name = name; obj.age = age; return obj; } function createFruit(name, color){ var obj = new Object(); obj.name = name; obj.color = color; return obj; } var s1 = createStudent("easy", 20); var f1 = createFruit("apple", "green"); console.log(s1,f1); // Object {name: "easy", age: 20} Object {name: "apple", color: "green"}
总结:对于以上代码创建的对象s1、f1,我们用instanceof操作符去检测,他们统统都是Object类型,而我们希望s1是Student类型的,而f1是Fruit类型的,为了实现这个目标,我们可以用自定义构造函数的方法来创建对象。
3、构造函数模式创建对象;
上面创建Object这样的原生对象的时候就使用过其构造函数:var obj = new Object();
创建原生数组Array类型对象时也使用过其构造函数:var obj = new Array();
那么我们现在介绍一下构造函数和普通函数有什么区别:
a、实际上并不存在创建构造函数的特殊语法,其与普通函数唯一的区别在于调用方法。对于任意函数,使用new操作符调用,那么它就是构造函数;不使用new操作符调用,那么它就是普通函数;
b、按照惯例,我们约定构造函数名以大写字母开头,普通函数以小写字母开头,这样有利于显性区分二者,例如上面的new Array(),new Object();
c、使用new操作符调用构造函数时,会经历(1)创建一个新对象;(2)将构造函数作用域赋给新对象(使this指向该新对象);(3)执行构造函数代码;(4)返回新对象;四个阶段;
了解构造函数和普通函数的区别后,我们用构造函数将工厂模式的函数重写,并添加一个方法属性,如:
function Student(name, age) { // 自定义构造函数Student this.name = name; this.age = age; this.alertName = function(){ alert(this.name) }; } function Fruit(name, color) { // 自定义构造函数Fruit this.name = name; this.color = color; this.alertName = function(){ alert(this.name) }; } var s1 = new Student("easy", 20); var f1 = new Fruit("apple", "green"); console.log(s1 instanceof Student); // true console.log(f1 instanceof Fruit); // true console.log(s1 instanceof Object); // true 任何对象均继承自Object console.log(f1 instanceof Object); // true 任何对象均继承自Object
总结:这样我们解决了工厂模式无法区分对象类型的尴尬,但是使用构造函数来创建对象时,我们发现,Student和Fruit对象中有同样的方法,所以我们完全可以将对象方法(函数)移到构造函数外部,于是就有了原型模式创建对象。
4、原型模式创建对象;
原型链甚至原型继承,是整个JS中最难的一部分也是最不好理解的一部分,在此没有过多介绍,对js有兴趣的话,可以去查阅一下相关JS原型的一些知识点。
下面是原型模式创建对象的示例:
function Student() { this.name = 'easy'; this.age = 20; } Student.prototype.alertName = function(){ // Student.prototype是Student的父类 alert(this.name); }; var stu1 = new Student(); var stu2 = new Student(); stu1.alertName(); // easy stu2.alertName(); // easy alert(stu1.alertName == stu2.alertName); // true 二者共享同一函数
二、定时器
js中的定时器分两种:setTimeout()、setInterval()。
setTimeout()和setInterval()是HTML DOM Window对象的两个方法。
1、setTimeout():在指定的毫秒数后执行指定代码(一次性定时器)
语法:myVar = window.setTimeout(回调函数,毫秒数); 例如:
<button>点我</button> <p>取消</p> <script type="text/javascript"> var oBtn = document.getElementsByTagName('button')[0]; var oP = document.getElementsByTagName('p')[0]; oBtn.onclick = function myFunction(){ var timer = setTimeout(function(){ alert("Hello") },3000); } oP.onclick = function () { clearTimeout(timer); // 停止执行setTimeout()方法的函数代码 } </script>
总结:
1)window.setTimeout 和window.clearTimeout()方法可以不使用window 前缀;
2)一次性定时器可以做异步(数据交互时,若数据阻塞了,可以考虑加一个一次性定时器来处理);
2、setInterval():间隔指定的毫秒数不停地执行指定的代码,例如:
语法:window.setInterval(回调函数,毫秒数); 例如:
<p>页面上显示时钟:</p> <p id="demo"></p> <button onclick = "myStopFunction()">停止</button> <script> var timer = setInterval(function(){myTimer()},1000); function myTimer(){ var d = new Date(); var t = d.toLocaleTimeString(); document.getElementById("demo").innerHTML = t; } function myStopFunction(){ clearInterval(timer); } </script>
总结:
1)window.setInterval()和window.clearInterval()方法可以不使用window前缀;
2)可以做动画;
注意:js跟python一样,都有垃圾回收机制,但是垃圾回收不能收回定时器对象,所以记得关定时器。两种方法根据不同的场景和业务需求择而取之,对于这两个方法,需要注意的是如果要求在每隔一个固定的时间间隔后就精确地执行某动作,那么最好使用setInterval,而如果不想由于连续调用产生互相干扰的问题,尤其是每次函数的调用需要繁重的计算以及很长的处理时间,那么最好使用setTimeout。
三、BOM
BOM:Browser Object Model,浏览器对象模型。
window对象是BOM的顶级(核心)对象,所有对象都是通过它延伸出来的,也可以称为window的子对象。因此DOM是BOM的一部分。
window对象:
window对象是JavaScript中的顶级对象;
全局变量、自定义函数也是window对象的属性和方法;
window对象下的属性和方法调用时,可以省略window;
下面介绍几个BOM的常见内置方法和内置对象:
1、打开窗口、关闭窗口
window.open(url,target); // window可不写 // url: 要打开的地址 target: _blank 、_self 、_parent
2、location对象
window.location可以简写成location。location相当于浏览器地址栏,可以将url解析成独立的片段。
a、location对象的属性:
1)href:跳转;
2)hash: 返回url中#后面的内容,包含#;
3)host: 主机名,包括端口;
4)hostname: 主机名;
5)pathname: url中的路径部分;
6)protocol: 协议,一般是http、https;
7)search: 查询字符串;
b、location对象的方法:
1)location.reload():重新加载,例如:
setTimeout(function(){ // 3 秒之后让网页整个刷新 window.location.reload(); },3000)
3、history对象(用的不多,因为浏览器中已自带了这些功能的按钮)
window.history 对象包含浏览器的历史,在编写时可不使用 window 这个前缀。
a、后退(与在浏览器点击后退按钮相同)
history.back();
history.go(-1);
b、前进(与在浏览器中点击向前按钮相同)
history.forward();
history.go(1);
c、刷新(与在浏览器中点击刷新钮相同)
history.go(0);
4、navigator对象
window.navigator 对象包含有关访问者浏览器的信息,在编写时可不使用 window 这个前缀。
window.navigator 的一些属性可以获取客户端的一些信息,例如:
userAgent:用户代理,系统,浏览器;
platform:硬件平台,浏览器支持的系统,win/mac/linux;
注意:来自 navigator 对象的信息具有误导性,不应该被用于检测浏览器版本,这是因为:
1)navigator 数据可被浏览器使用者更改;
2)一些浏览器对测试站点会识别错误;
3)浏览器无法报告晚于浏览器发布的新操作系统;
四、位置信息(client、offset、scroll系列)
1、client系列
<div class="box" style="width: 200px; height: 200px; border: 10px solid red; padding: 80px;"></div> <script type="text/javascript"> /* * clientTop 内容区域到边框顶部的距离,说白了,就是边框的高度 * clientLeft 内容区域到边框左部的距离,说白了就是边框的宽度 * clientWidth 内容区域 + 左右padding 可视宽度 * clientHeight 内容区域 + 上下padding 可视高度 */ var oBox = document.getElementsByClassName('box')[0]; console.log(oBox.clientTop); // 10 console.log(oBox.clientLeft); // 10 console.log(oBox.clientWidth); // 360 console.log(oBox.clientHeight) // 360 </script>
应用:获取屏幕的可视区域
<script type="text/javascript"> // 屏幕的可视区域 window.onload = function(){ // document.documentElement 获取的是html标签 console.log(document.documentElement.clientWidth); console.log(document.documentElement.clientHeight); // 窗口大小发生变化时,会调用此方法 window.onresize = function(){ console.log(document.documentElement.clientWidth); console.log(document.documentElement.clientHeight); } } </script>
2、offset系列
<div class="wrap" style=" width: 300px; height: 300px; background-color: green; margin-left: 20px; position: relative;"> <div id="box" style="width: 200px; height: 200px; border: 5px solid red; position: absolute; top:50px; left: 30px;"> </div> </div> </body> <script type="text/javascript"> window.onload = function(){ var oBox = document.getElementById('box'); /* * offsetWidth 占位宽 内容 + padding + border * offsetHeight 占位高 * offsetTop: 如果盒子没有设置定位 到body的顶部的距离,如果盒子设置定位,那么是以父辈为基准的top值 * offsetLeft: 如果盒子没有设置定位 到body的左部的距离,如果盒子设置定位,那么是以父辈为基准的left值 */ console.log(oBox.offsetWidth); // 210 console.log(oBox.offsetHeight); // 210 console.log(oBox.offsetTop); // 50 console.log(oBox.offsetLeft); // 30 } </script>
3、scroll系列
<body style="width: 2000px; height: 2000px;"> <div style="height: 200px;background-color: red;"></div> <div style="height: 200px;background-color: green;"></div> <div style="height: 200px;background-color: yellow;"></div> <div style="height: 200px;background-color: blue;"></div> <div style="height: 200px;background-color: gray;"></div> <div id = 'scroll' style="width: 200px;height: 200px;border: 1px solid red;overflow: auto;padding: 10px;margin: 5px 0px 0px 0px;"> <p style="height: 800px;">这里是内容</p> </div> </body> <script type="text/javascript"> window.onload = function(){ //实时监听滚动事件 window.onscroll = function(){ console.log(1111); console.log('上'+document.documentElement.scrollTop); console.log('左'+document.documentElement.scrollLeft); console.log('宽'+document.documentElement.scrollWidth); console.log('高'+document.documentElement.scrollHeight); }; var oS = document.getElementById('scroll'); oS.onscroll = function(){ // scrollHeight : 内容的高度 + padding 不包含边框 console.log('上'+oS.scrollTop); console.log('左'+oS.scrollLeft); console.log('宽'+oS.scrollWidth); console.log('高'+oS.scrollHeight); } } </script>