JavaScript高级(01)
前端开发工具
1.1、 WebStorm介绍和下载
l 介绍
WebStorm是JetBrains 推出的一款强大的HTML5编辑工具,拥有丰富的代码快速编辑,可以智能的补全代码、代码格式化、html提示以及代码检查和快速修复等,支持不同浏览器的提示,同时也是一款JavaScript 开发工具,拥有即时编辑(chrome)、自动完成、debugger、Zen Coding、HTML5 支持、JSLint、Less支持、CoffeeScript支持、Node.JS、单元测试、集成git和svn版本控制等特性,推荐前端工程师使用。
WebStorm被广大中国JS开发者誉为“Web前端开发神器”
l 官网:http://www.jetbrains.com/webstorm/
js的基础回顾
// 1、JS中数据类型有哪些?
// JS中有6种数据类型,其中五种基本数据类型(Number,Boolean,String,Undefined,Null)和一种复合数据类型(Object)
console.log('--------------------JS中数据类型有哪些END------------------------');
// 2、如何判断变量数据的类型?
// 使用typeof来判断变量的数据类型
var i = 12; // 'number'
var s = 'abc'; // 'string'
var b = true; // 'boolean'
var u = undefined; // undefined
var oDate = new Date(); // 'object'
var arr = [12,5]; // 'object'
var o = {}; // 'object'
var fn = function(){alert('xxx')}; // 'function'
var n = null; // 'object'
console.log(typeof i);
console.log(typeof s);
console.log(typeof b);
console.log(typeof u);
console.log(typeof oDate);
console.log(typeof arr);
console.log(typeof o);
console.log(typeof fn);
console.log(typeof n);
// 注意点:
// 1. JS解释器认为null是object数据类型的一种特殊形式,而null在JS里面特指空对象
// 2. function(){}的数据类型是function, 也就是说function也是一种基本数据类型,而不是对象的一种特殊形式。实际上在JS中,函数是一个极为容易引起误解或者引发歧义的数据类型,它可以是独立的数据类型,也可以被称为类或者构造函数,还可以作为函数对象等。
console.log('--------------------如何判断变量数据的类型END------------------------');
// 3、JS中的空类型有哪些?
// 1).null 是一个原始的数据类型,只有一个值null, 特指空对象
// 2).undefined是一个原始的数据类型,只有一个值undefined
// 1、定义变量没有赋值,此时变量的值是undefined
var a;
console.log(a);// undefined
///2、函数没有返回值或者没有返回具体的值都是默认返回undefined
function show() {
console.log('我没有返回值,默认返回undefined');
}
console.log(show()); // undefined
///3、访问对象中一个不存在的属性
console.log(window.abc); // undefined
console.log('--------------------JS中的空类型有哪些END------------------------');
// 4、JS中代表哪些数据代表false?
// 数字0、空字符串''、false、空对象null、NaN、undefined
// 5、JS中 === 和 == 有什么区别?
// == 用来比较两个变量的值是否相等,先做数据类型的转换,在做比较
// === 全等,严格的比较,先比较数据类型,数据类型不相等,就立刻返回false
console.log('1' == 1); // true
console.log('1' === 1); // false
console.log('--------------------JS中 === 和 == 有什么区别END------------------------');
// 6、JS中的in运算符有什么用?
// 1). 用来循环数组,性能低,建议使用普通的for
var arr = [12,5,8];
for (var i in arr) {
console.log(i + '---' + arr[i]); // 0-12 1-5 2-8
}
// 2). 用来循环对象
var p = {
name: 'Jack',
age: 20,
gender: 'male'
};
for (var name in p) {
console.log(name + '---' + p[name]); // 'name---Jack' age---20 'gender---male'
}
// 属性操作:
// i). 点 . 比较方面,不能接收变量
// ii). 中括号 [] 可以接收变量,可以替代所有点出现的位置
// 3). 用来判断某个属性是否属于某一个对象
console.log('name' in p); // true
console.log('abc' in p); // false
console.log('--------------------JS中的in运算符有什么用END------------------------');
// 7、JS中的逻辑中断?
// 且&& 或 ||
// && 当左侧为false,直接返回左侧的结果;当左侧结果为true,返回右侧结果
// || 当左侧为true,直接返回左侧结果; 当左侧结果为false,返回右侧结果
console.log(1 || 2); // 1
console.log(0 || 2); // 2
console.log(null || 0); // 0
面向对象的介绍:那么什么是对象呢?这里只需要举出相关例子就是可以不需要准确说出概念
面向过程:完成一件事情的所有步骤都亲力亲为,一步一步来完成。例如要吃饺子,就必须自己剁馅儿、和面、擀饺子皮儿、包饺子
面向对象:完成一件事情,直接去找能做这件事的人。例如吃饺子,直接找老婆(如果没有就去饺子馆吧)
面向过程:是事件的执行者
面向对象:是指挥者
一言以蔽之:面向对象就是对面向过程的封装!
那么为什么要面向对象呢?
1) 提高代码的复用性,简化开发
2) 使代码结构清晰
3) 在JS中有一个特殊的作用:防止代码污染
那么什么是代码污染呢?代码污染其实就是代码中含有重复的变量并且其中后面的代码吧前面的代码给覆盖了,就是再调用的时候不知道找不到自己真实的需要调用的那个对象或者是方法
如何解决代码污染?
1、我们可以把定义的方法放在对象中里面,然后使用对象调用自己的方法基本上可以防止代码污染如下:
创建对象的两种方式:
第一种就是使用对象的直接量的方式:
在定义对象的时候,直接使用JSON格式来定义一个JS对象,并且为这个对象赋值属性和方法,称为对象的直接量(字面量)
这种方式创建的对象,默认是Object类型的对象(这种方式创建object对象)
l 案例代码:(也就是使用json格式的数据来定义对象称作为对象的直接量)(也就是使用json格式的数据来定义对象实现这个过程)
效果如下:
l 缺陷:
u 只能使用1次,无法重复利用,每次都要编写相同代码创建新对象
l 使用场景:
u 对象只需要一次使用的时候。比如作为传递参数;
u 自己封装JS框架(函数)的时候。
第二种方式就是使用构造函数创建对象
l 构造函数创建对象的一般步骤:
1) 通过function指定一个构造函数,与普通函数没差别,只是约定首字母大写以区分
2) 然后在构造函数中通过this.属性名=属性值来完成对象属性初始化。
3) 最后通过new关键字创建对象(实例)
其中的代码案例:
效果如下:
那么对象中的函数相同吗?
测试:
结果显示:
实际上查看内存中对象的属性发现p1和p2中各有一份 sayHello 方法:
结论:
通过上面的实验我们发现,对象中的所有属性,包括定义的方法,都是每个对象独有的,不会共享。
属性不共享可以理解,但是方法都是一样的,如果也不共享,那么就是对内存的极大浪费。
l 优势:
u 对象可以重复创建
l 缺点:
u 对象中相同的方法,无法实现共享,内存占用高
由上面可以引出来对象原型的概念
对象原型(prototype)
在JS中,每一个构造函数都会有一个prototype(也是一个对象)属性,任何由同一个构造函数创建的对象,都会共享这个prototype对象,并且可以具备这个prototype的所有属性(成员)
原型的基本的使用方法
刚开始的时候没有设置对象原型的时候,定义一个空的构造函数,只给出name属性,当打印age属性的时候结果是undefined,因为没有给属性
结果:
打印控制台中是undefined的。
查看对象属性也是只有name属性,没有age:
当使用原型给构造函数添加新的属性的时候,也就是使用prototype给构造函数添加新的属性
此时控制台上已经显示了属性
这个时候再次查看对象的属性:
发现p1和p2对象中虽然依然没有age,但是构造函数Person的prototype中已经有age了,又因为对象会共享prototype的成员,所以每个对象都可以使用age属性了!
例外一种情况进行总结:
1.1.1.1、 给对象从原型中继承的属性赋值
尝试修改对象中,继承自prototype的属性值age:
结果:p1的age已经变为30, p2没变
那么问题来了:
问题,既然是共享的属性,那么为什么p1修改了,p2值没变?
查看内存中的状态:
我们发现:prototype中的age没有改变,而是在对象p1中新增了自己的age属性,并且赋值为30
结论:当原型和对象自身都有相同属性时,对象中的属性优先!
1.1.1.1、 总结
1) 当我们访问对象中的属性时,默认会先在当前对象中查找;如果在当前对象找不到,就会去对象的prototype中查找
a) 事实上,prototype也是对象,因此在prototype对象中找不到,会到prototype对象的prototype中找,逐级向上形成“原型链”,原型链的最顶级的是Object.prototype
b) 那么Object.prototype也是对象,再向上还有吗?没有了,再向上是null。Object.prototype就是原型链的根
2) 修改对象的属性,不会修改prototype中的属性,而是在对象中创建新的属性
3) 某些浏览器支持__proto__属性,与prototype是同一个东西,但是某些浏览器还不支持。所以一般不要用
再有一种情况就是通过原型来更改构造函数
为了减少对象内存占用,我们一般创建构造函数的时候,会把经常变化的属性在构造函数中声明,每个对象都有自己的属性。然后把公用的不变化的东西(通常是函数)通过原型来添加。
此时的验证结果显示:
每个对象都可以调用sayHello方法,证明共享了方法。 各个对象的sayHello方法判断是相等的。证明内存中只有一份。
总结构造函数创建对象的方法:
1、 构造函数里面写变化属性
2、 原型上去添加方法
通过原型扩展js的原生对象
事实上不仅仅我们自己定义的对象有原型,JS中原生的对象也有原型。我们可以通过原生对象的原型对原生的JS进行扩展!
原生的JS中,Array对象并没有sum方法,尝试调用报错:
我们使用原型进行扩展:
结果显示:
疑问?
扩展字符串的trim方法
终极总结:判断一个 对象的类型
那么如何判断一个对象的类型呢?
1)instance of
2)通过类的字节码Class对象
方式一:instanceof作用是用来判断一个对象是否属于一个类
案例代码:
结果显示:
由此得出的总结结论:instanceof 可以基本准确的判断对象的所属类型,但是当 instanceof后面跟的是类型是父类类型的时候,判断是不准确的。这一点与Java类似
如果要是更准确的来判断对象类型的话,是可以通过类的字节码对象,也就是和java中的反射技术是差不多的,但是js中是没有类的概念的,更不要说class对象,但是js中类似的概念是构造函数constructor
也就是所说的方式2 :作用constructor用来检测直接的构造者
通过constructor来准确判断对象类型
结果显示的也是返回的是布尔值
this关键字的总结介绍:
在Java中,this关键字表示的是当前对象。比如在方法中使用,就是调用方法的对象。
在JavaScript中,this也是类似的。只不过JS中方法无需定义在类中,所以很多人对this的含义就懵逼了。
代码案例的实现:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>this关键字的含义</title>
</head>
<body>
<script>
// 演示: this关键字的含义
// this指的是当前的方法属于谁,只看调用,谁调用就指向谁,所以我们只需要搞清楚调用方法的对象即可
// 1. 全局函数中的this
function show() {
console.log('全局函数中的this:' + this);
}
// 全局函数 默认是注册到window对象上中
// 而调用window中的任何成员,默认是可以省略window.的
// 这里的show()完整的写法其实是:window.show(); 因此肯定当前的方法属于window这个对象
// show(); // Object window
window.show();
// 2. 对象中的this
var p = {
name: 'Jack',
age: 20,
gender: 'male',
sayHello: function() {
console.log('Hello, I am' + this.name + ',' + this.age + 'years old');
}
};
// 对象中的this,指向的是调用该方法的对象,现在该方法属于p这个对象,因此this指向了p
p.sayHello(); // 'Hello, I amJack,20years old'
// 3. 事件函数中的this
// 当前的事件注册到了document对象身上
// 事件触发时,调用该事件处理函数的对象就是事件源对象,也就是document对象,此时事件函数里面的this指向了事件源对象
document.onclick = function() {
console.log('事件函数中的this:' + this); //object HTMLDocument
};
// 4. 定时器里面的this
// setTimeout方法本身就是window对象的一个方法,那么时间到了以后,
// 定时器里面的函数有谁来调用? window, 所以定时器里面的this就是window
setTimeout(function() {
console.log('定时器里面的this:' + this); // object Window
}, 1000);
</script>
</body>
</html>
关于this关键字进行总结:
1) 其实记住一点就够了:this指的是当前的方法属于谁,只看调用,谁调用就指向谁
2) 对象外的全局函数,this是window
3) 对象中的方法,被对象调用时,this是对象自己
4) 事件处理函数,this是事件绑定的对象
5) 定时任务函数,this是window
3.8 、对象的继承(组合式继承、构造函数继承、原型继承)
3.8.1 组合式继承:组合式继承就是把 一个对象的属性 全部加到另一个对象中。也被称为属性拷贝。
应用:组合式继承主要用在 对象的直接量 继承另一个 对象的直接量时。
案例:
结果显示:
使用的场景:比如我用对象封装了一个框架,现在要对该框架的方法进行扩展,新增更多方法。此时就可以把新增的方法定义到新的对象中,使用组合式继承来完成 方法的扩展。
//比如可以通过一个匿名对象,给o1可以扩展更多的方法
结果显示
3.8.2 构造函数继承
如果对象不是 直接量对象,而是通过构造函数new出来的,那么如何继承另一个构造函数中的属性呢?
结果显示:
我们发现直接在子类的构造函数中直接调用父类的构造函数不能实现属性的继承,因为直接调用父类的构造函数,此时父类的构造函数属于全局函数,所以里面的this指向了window对象,不是Worker的实例,这个时候我们要去改变父类构造函数里面this的指向,让父类构造函数里面的this指向Worker的实例
函数也是对象,任何函数都可以调用两个方法:call和apply ,来自于Function的原型
call和apply都会导致调用的函数被执行,但是可以在执行时指定this
名称 |
用法 |
参数说明 |
call |
fn.call(fn函数里面this的值,参数1,参数2..); |
第一个参数是被调用函数里面this的值,真实的参数从第二个开始 |
apply |
fn.apply(fn函数里面this的值, [参数1,参数2..]); |
同上,实际参数是数组结构 |
结果显示:
我们发现,worker具备了父类中的所有属性,但是,Person类在原型中扩展的方法 sayHello 并没有被继承。访问时报错
并且,在执行instanceof的时候,无法判断worker属于Person类的实例
特点:
1) 可以继承父类构造函数中定义的属性
2) 父类原型中定义的方法无法访问,扩展性差
3) instanceof 判断失效,因为子类原型与父类原型没有关联
3.8.3 使用的是原型继承;
为了解决上面的问题我们可以使用的就是原型继承的方式进行实现这个过程:
总结(非常重要可以查看)
JS的继承步骤:
1) 在你的构造函数中,调用父类的构造,但是要用call或apply
2) 让你的构造函数的prototype指向父类的对象
3) 因为原型被覆盖,因此原型中的constructor也被覆盖,需要修正constructor指向子类的构造函数
注意:原型继承,其实是让子类原型指向了父类对象。 这样父类对象就 覆盖了子类prototype中的所有属性。其中constructor属性也被覆盖成了父类的。因此,在使用原型继承时,必须手动把子类的原型中的constructor属性修改为子类的构造函数!
JavaScript高级(01)的更多相关文章
- javascript高级编程笔记01(基本概念)
1.在html中使用JavaScript 1. <script> 元素 <script>定义了下列6个属性: async:可选,异步下载外部脚本文件. charset:可选, ...
- 阅读摘录《javascript 高级程序设计》01
前言: 因为工作需要,所以开始主攻前台JS方面的技术.在以前的工作中,使用过这门脚本语言.但是都是比较凌乱的,用到什么学什么,只是为了实现业务,而去使用. 不会考虑到代码优化,封装对象等.今次特意借了 ...
- 读书笔记(01) - JSON - JavaScript高级程序设计
JSON与JavaScript对象 JSON是一种表示结构化数据的存储格式,语法格式上与JavasScript对象有些类似. TIPS: 与JavaScript对象的格式区别 不支持变量.函数或对象实 ...
- javascript高级特性
01_javascript相关内容02_函数_Arguments对象03_函数_变量的作用域04_函数_特殊函数05_闭包_作用域链&闭包06_闭包_循环中的闭包07_对象_定义普通对象08_ ...
- JavaScript高级---组合模式设计
一.设计模式 javascript里面给我们提供了很多种设计模式: 工厂.桥.组合.门面.适配器.装饰者.享元.代理.观察者.命令.责任链 在前面我们实现了工厂模式和桥模式 工厂模式 : 核心:为了生 ...
- JavaScript高级---桥模式设计
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
- javascript高级特性(面向对象)
javascript高级特性(面向对象): * 面向对象: * 面向对象和面向过程的区别: * 面向对象:人就是对象,年龄\性别就是属性,出生\上学\结婚就是方法. * 面向过程:人出生.上学.工作. ...
- 读书时间《JavaScript高级程序设计》一:基础篇
第一次看了<JavaScript高级程序设计>第二版,那时见到手上的书,第一感觉真是好厚的一本书啊.现在再次回顾一下,看的是<JavaScript高级程序设计>第三版,并记录一 ...
- 《Javascript高级程序设计》阅读记录(四):第五章 下
这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较深入,而且实际使用价值较大的内容记录下来,并且注释上我的一些想法.做这个一方面是提升了我的阅读效果以及方便我以后阅 ...
- 《Javascript高级程序设计》阅读记录(一):第二、三章
<Javascript高级程序设计>阅读记录(一) 这个系列,我会把阅读<Javascript高级程序设计>之后,感觉讲的比较深入,而且实际使用价值较大的内容记录下来,并且注释 ...
随机推荐
- Linux和win7(win10)双系统时间错误问题 时间相差8小时
转载自 http://m.2cto.com/os/201204/126212.html 有修改 前一段时间刚装了centos 5.4和win7的双系统.发现win7的系统时间不对,机子没上网,每天开机 ...
- 手工删除crfclust.bdb文件
环境:RHEL 6.5 + Oracle 11.2.0.4 RAC 现象:巡检发现自己的测试环境节点2的空间使用率过高,进一步查询,发现大文件是GI目录下crfclust.bdb文件. crfclus ...
- SVG坐标系统及图形变换
前面的话 前面介绍过SVG视野后,本文将开始介绍SVG坐标系统及图形变换 坐标定位 对于所有元素,SVG使用的坐标系统或者说网格系统,和Canvas用的差不多(所有计算机绘图都差不多).这种坐标系统是 ...
- 读取Execl表 导入数据库
不知不觉博客园园林都两年多了,我是今年毕业的应届生,最近公司项目需要改动,很多的数据需要导入,很多的实体类需要些.考虑到这些问题自己写了两个winform版的小工具,一个是读取Execl数据导入数据库 ...
- java锁机制
2.4 锁机制 临界区是指,使用同一个锁控制的同一段代码区或多段代码区之间,在同一时间内最多只能有一个线程在执行操作.这个概念与传统的临界区有略微的差别,这里不想强调这些概念上的差别,临 ...
- 转: 【Java并发编程】之二十:并发新特性—Lock锁和条件变量(含代码)
简单使用Lock锁 Java5中引入了新的锁机制--Java.util.concurrent.locks中的显式的互斥锁:Lock接口,它提供了比synchronized更加广泛的锁定操作.Lock接 ...
- MITNIK ATTACK
Https 443 http 80 TCP/IP 协议栈:将数据封装包头 传输层报头 Ack回复确认位 FIN结束位 SIN 开始位 RST 重置位 Seq 序号位 网络层报头 目的地址 原地址 报文 ...
- 201521123102 《Java程序设计》第8周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 在实验中,Sc ...
- 201521123038 《Java程序设计》 第五周学习总结
201521123038 <Java程序设计> 第五周学习总结 1. 本周学习总结 2. 书面作业 1.代码阅读:Child压缩包内源代码 1.1 com.parent包中Child.ja ...
- Java 第三周总结
1.本周学习总结 2.书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; pub ...