本篇是快速学习JavaScript笔记的最后一篇,很多地方总结的不好,所以说的会比较详细。
前面两篇的快速学习笔记:
面向Android的快速学习JavaScript笔记(基础篇 上)
面向Android的快速学习JavaScript笔记(基础篇 中)
如有理解错误的地方,希望大家可以踊跃指出,我立即修改
最后继续附上廖雪峰大神的JavaScript详细教程
目录:
- 面向对象编程
- 基本概述
- 创建对象
- 原型继承
- class继承
- 浏览器
- 概述
- 浏览器对象
- 操作DOM
- 概述
- 更新DOM
- 插入DOM
- 删除DOM
- 操作表单
- 操作文件
- AJAX
- Promise
- Canvas
面向对象编程
基本概述
- 与Java不同,JS不使用类和实例的概念,JS使用原型来实现OOP
- JavaScript的原型链和Java的Class区别就在,它没有“Class”的概念
- 所有对象都是实例,所谓继承关系不过是把一个对象的原型指向另一个对象而已。
var Student = {
name: 'Robot',
height: 1.2,
run: function () {
console.log(this.name + ' is running...');
}
};
var xiaoming = {
name: '小明'
};
xiaoming.__proto__ = Student;
//小明的原型指向Student,所以现在小明也可以使用run()
//也就相当与Java的继承
!注意:
不要直接使用 obj.__proto__ 去指向原型,应使用下面这种方法
// 原型对象:
var Student = {
name: 'Robot',
height: 1.2,
run: function () {
console.log(this.name + ' is running...');
}
};
function createStudent(name) {
// 基于Student原型创建一个新对象:
var s = Object.create(Student);
// 初始化新对象:
s.name = name;
return s;
}
var xiaoming = createStudent('小明');
xiaoming.run(); // 小明 is running...
xiaoming.__proto__ === Student; // true
创建对象
- 原型链:指定对象属性的时候会根据原型链一层一层往上找,找到了就返回,直到找的是null
var arr = [1, 2, 3];
其原型链是:
arr ----> Array.prototype ----> Object.prototype ----> null
//原型链越长,访问对象属性的时间就越长,所以原型链不应过长
- 构造函数
function Student(name) {
this.name = name;
this.hello = function () {
alert('Hello, ' + this.name + '!');
}
}
//使用new来创建对象
var xiaoming = new Student('小明');
xiaoming.name; // '小明'
xiaoming.hello(); // Hello, 小明!
不使用new就返回undefined
使用new就会默认返回this,this指向这个对象本身
使用new 创建的对象还从原型上获得了一个constructor属性,它指向函数Student本身:
xiaoming.constructor === Student.prototype.constructor; // true
Student.prototype.constructor === Student; // true
Object.getPrototypeOf(xiaoming) === Student.prototype; // true
xiaoming instanceof Student; // true
xiaoming.name; // '小明'
xiaohong.name; // '小红'
xiaoming.hello; // function: Student.hello()
xiaohong.hello; // function: Student.hello()
xiaoming.hello === xiaohong.hello; // false
这里不同对象的hello函数是不一样的,不过他们对于我们使用来说应该是一样的才行,所以
function Student(name) {
this.name = name;
}
Student.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
};
可以让Student的原型去创造hello函数
这样后面的student对象使用的hello就一样了
- 比较好的创建方式:
对于忘记使用new的话,this指向的就是window对象,也就是在全局创建了一个name属性
比较合理的创建对象的构造应该是这样的:
function Student(props) {
this.name = props.name || '匿名'; // 默认值为'匿名'
this.grade = props.grade || 1; // 默认值为1
}
Student.prototype.hello = function () {
alert('Hello, ' + this.name + '!');
};
function createStudent(props) {
return new Student(props || {})
}
原型继承
- JS中继承上通过原型指向来实现继承
- 而一般的方法就是创造一个中间对象来实现
- 重点把握原型指向 和 原型的构造函数修复问题上
// PrimaryStudent构造函数:
function PrimaryStudent(props) {
Student.call(this, props);
this.grade = props.grade || 1;
}
// 空函数F:
function F() {
}
// 把F的原型指向Student.prototype:
F.prototype = Student.prototype;
// 把PrimaryStudent的原型指向一个新的F对象,F对象的原型正好指向Student.prototype:
PrimaryStudent.prototype = new F();
// 把PrimaryStudent原型的构造函数修复为PrimaryStudent:
PrimaryStudent.prototype.constructor = PrimaryStudent;
// 继续在PrimaryStudent原型(就是new F()对象)上定义方法:
PrimaryStudent.prototype.getGrade = function () {
return this.grade;
};
// 创建xiaoming:
var xiaoming = new PrimaryStudent({
name: '小明',
grade: 2
});
xiaoming.name; // '小明'
xiaoming.grade; // 2
// 验证原型:
xiaoming.__proto__ === PrimaryStudent.prototype; // true
xiaoming.__proto__.__proto__ === Student.prototype; // true
// 验证继承关系:
xiaoming instanceof PrimaryStudent; // true
xiaoming instanceof Student; // true
- 简要封装:
//实现对象之间的继承函数
function inherits(Child, Parent) {
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
}
class继承
- 在ES6中才引入的关键词class
- 作用:简化继承,减少代码量
- 与Java基本一致,比较容易理解
//使用class创建对象
class Student {
constructor(name) {
this.name = name;
}
hello() {
alert('Hello, ' + this.name + '!');
}
}
//继承的使用
class PrimaryStudent extends Student {
constructor(name, grade) {
super(name); // 记得用super调用父类的构造方法!
this.grade = grade;
}
myGrade() {
alert('I am at grade ' + this.grade);
}
}
浏览器
概述
主要浏览器:
-
IE 6~11:国内用得最多的IE浏览器,历来对W3C标准支持差。从IE10开始支持ES6标准;
-
Chrome:Google出品的基于Webkit内核浏览器,内置了非常强悍的JavaScript引擎——V8。由于Chrome一经安装就时刻保持自升级,所以不用管它的版本,最新版早就支持ES6了;
-
Safari:Apple的Mac系统自带的基于Webkit内核的浏览器,从OS X 10.7 Lion自带的6.1版本开始支持ES6,目前最新的OS X 10.11 El Capitan自带的Safari版本是9.x,早已支持ES6;
-
Firefox:Mozilla自己研制的Gecko内核和JavaScript引擎OdinMonkey。早期的Firefox按版本发布,后来终于聪明地学习Chrome的做法进行自升级,时刻保持最新;
-
移动设备上目前iOS和Android两大阵营分别主要使用Apple的Safari和Google的Chrome,由于两者都是Webkit核心,结果HTML5首先在手机上全面普及(桌面绝对是Microsoft拖了后腿),对JavaScript的标准支持也很好,最新版本均支持ES6。
需要注意:某某安全浏览器,某某旋风浏览器,它们只是做了一个壳,其核心调用的是IE
对于编写JavaScript的时候,就要充分考虑到浏览器的差异,尽量让同一份JavaScript代码能运行在不同的浏览器中
浏览器对象
-
window:
- 不但充当全局作用域,也表示浏览器窗口
- innerWidth属性:获取浏览器窗口内部的宽度
- innerHeight属性:获取浏览器窗口内部的高度
- outerWidth属性:获取浏览器窗口整个的宽度
- outerHeight属性:获取浏览器窗口整个高度
-
navigator:
- 浏览器 信息对象
-
navigator.appName
:浏览器名称; -
navigator.appVersion
:浏览器版本; -
navigator.language
:浏览器设置的语言; -
navigator.platform
:操作系统类型; -
navigator.userAgent
:浏览器设定的User-Agent字符串。 - navigator信息容易被修改,为了针对不同浏览器 :
var width;
if (getIEVersion(navigator.userAgent) < 9) {
width = window.innerWidth || document.body.clientWidth;
}
-
screen:
- 屏幕信息对象
-
screen.width
:屏幕宽度,以像素为单位; -
screen.height
:屏幕高度,以像素为单位; -
screen.colorDepth
:返回颜色位数,如8、16、24。
-
location:
- 当前页面的URL信息对象
location.href; //http://www.example.com:8080/path/index.html?a=1&b=2#TOP
location.protocol; // 'http'
location.host; // 'www.example.com'
location.port; // '8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'
`location.assgin('/di');` //加载新页面
`location.reload();` //重新加载当前页面
-
document
- 由于HTML在浏览器中以DOM形式表示为树形结构,document对象就是整个DOM树的根节点。
- document的title就是HTML中的'title内容读取
document.title='hahahha';
。 -
document.getElementById(id)
根据传入id获取节点对象 -
document.getElementsByTagName()
根据 TagName读取节点对象 -
document.cookie;
获取当前页面的cookie信息
-
history
- 浏览器的历史记录信息对象
-
history.forward()
前进 -
history.back()
后退 - 任何时候都不应使用history对象
操作DOM
概述:
-
更新:更新该DOM节点的内容,相当于更新了该DOM节点表示的HTML的内容;
-
遍历:遍历该DOM节点下的子节点,以便进行进一步操作;
-
添加:在该DOM节点下新增一个子节点,相当于动态增加了一个HTML节点;
-
删除:将该节点从HTML中删除,相当于删掉了该DOM节点的内容以及它包含的所有子节点。
-
代码常用做法:
// 返回ID为'test'的节点:
var test = document.getElementById('test');
// 先定位ID为'test-table'的节点,再返回其内部所有tr节点:
var trs = document.getElementById('test-table').getElementsByTagName('tr');
// 先定位ID为'test-div'的节点,再返回其内部所有class包含red的节点:
var reds = document.getElementById('test-div').getElementsByClassName('red');
// 获取节点test下的所有直属子节点:
var cs = test.children;
// 获取节点test下第一个、最后一个子节点:
var first = test.firstElementChild;
var last = test.lastElementChild;
//版本<IE8是不支持下面功能的
// 通过querySelector获取ID为q1的节点:
var q1 = document.querySelector('#q1');
// 通过querySelectorAll获取q1节点内的符合条件的所有节点:
var ps = q1.querySelectorAll('div.highlighted > p');
更新DOM
- innerHTML方式修改
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本为abc:
p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
// 设置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p>的内部结构已修改
- innerText或textContent方式修改
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本:
p.innerText = '<script>alert("Hi")</script>';
// HTML被自动编码,无法设置一个<script>节点:
// <p id="p-id"><script>alert("Hi")</script></p>
版本<IE9是不支持textContent
- 修改节点的css样式
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px';
p.style.paddingTop = '2em';
插入DOM
- appendChild(节点对象) :将子节点添加到到父节点最后
- createElement(什么节点) :创建一个新的节点
- insertBefore(newElement, referenceElement);插入节点
<!-- HTML结构 -->
<p id="js">JavaScript</p>
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>
var
js = document.getElementById('js'),//获取节点
list = document.getElementById('list');
list.appendChild(js);//在尾部添加节点
var
python=document.getElementById('python');//获取python节点
haskell = document.createElement('p'); //创建节点
haskell.id = 'haskell'; //设置节点属性
haskell.innerText = 'Haskell';
list.innerBefore(haskell,python);
<!-- HTML结构 -->
<div id="list">
<p id="java">Java</p>
<p id="haskell">Haskell</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
<p id="js">JavaScript</p>
</div>
删除DOM
- 删除节点以后节点数动态变化
-
child.parentElement;
获取当前节点的父节点 -
parent.removeChild(child);
获取父节点然后调用remove传入要删除的节点对象
操作表单
-
HTML表单中的输入控件:
-
文本框,对应的
<input type="text">
,用于输入文本; -
口令框,对应的
<input type="password">
,用于输入口令; -
单选框,对应的
<input type="radio">
,用于选择一项; -
复选框,对应的
<input type="checkbox">
,用于选择多项; -
下拉框,对应的
<select>
,用于选择一项; -
隐藏文本,对应的
<input type="hidden">
,用户不可见,但表单提交时会把隐藏文本发送到服务器。
-
-
获取与修改值:
// <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
// <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label>
var mon = document.getElementById('monday');
var tue = document.getElementById('tuesday');
mon.value; // '1'
tue.value; // '2'
//对于选框要使用checked来获取
mon.checked; // true或者false
tue.checked; // true或者false
- 提交表单;
- 1、调用表单对象的submit(),不过会影响了form的正常提交
- 2、响应form的onSubmit事件
!-- HTML -->
<form id="test-form" onsubmit="return checkForm()">
<input type="text" name="test">
<button type="submit">Submit_Two</button>
<button type="button" onclick="doSubmitForm()">Submit_One</button>
</form>
//第一种方式
<script>
function doSubmitForm() {
var form = document.getElementById('test-form');
// 可以在此修改form的input...
// 提交form:
form.submit();
}
</script>
//第二种港式
<script>
function checkForm() {
var form = document.getElementById('test-form');
// 可以在此修改form的input...
// 继续下一步:
return true;
}
</script>
操作文件
- 获取文件url:
var f = document.getElementById('test-file-upload');
var filename = f.value; // 'C:\fakepath\test.png'
- H5新增的File API提供了对File文件操作的支持
var
fileInput = document.getElementById('test-image-file'),
info = document.getElementById('test-file-info'),
preview = document.getElementById('test-image-preview');
// 监听change事件:
fileInput.addEventListener('change', function () {
// 清除背景图片:
preview.style.backgroundImage = '';
// 检查文件是否选择:
if (!fileInput.value) {
info.innerHTML = '没有选择文件';
return;
}
// 获取File引用:
var file = fileInput.files[0];
// 获取File信息:
info.innerHTML = '文件: ' + file.name + '<br>' +
'大小: ' + file.size + '<br>' +
'修改: ' + file.lastModifiedDate;
if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
alert('不是有效的图片文件!');
return;
}
// 读取文件:
var reader = new FileReader();
reader.onload = function(e) {
var
data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...'
preview.style.backgroundImage = 'url(' + data + ')';
};
// 以DataURL的形式读取文件:
reader.readAsDataURL(file);
});
- 回调:读取文件一般都是异步的操作:
reader.readAsDataURL(file);
reader.onload = function(e) {
// 当文件读取完成后,自动调用此函数:
};
AJAX
AJAX: Asynchronous JavaScript and XML :用JavaScript执行异步网络请求
这里直接跳到网页去看吧:
走你: AJAX
Promise
用于封装异步操作,以便根据异步操作是否成功来进行后续的操作。
走你:Promise
Canvas
- HTML5新增的组件,用于绘制动画图标等
- HTML中canvas的声明定义
- canvas的获取
- canvas的使用 : 这里的使用和Android中十分相似,很好理解
- canvas绘制坐标如下
canvas在HTML中的定义
<canvas id="test-stock" width="300" height="200">
<p>Current Price: 25.51</p>//浏览器对H5的支持不一致,所以最好加上说明性代码,这一句就是,如果浏览器支持,就会忽略这一句代码
</canvas>
var ctx = canvas.getContext('2d');//获取2Dcanvas
var gl = canvas.getContext("webgl");//获取3D canvas
ctx.clearRect(0, 0, 200, 200); // 擦除(0,0)位置大小为200x200的矩形,擦除的意思是把该区域变为透明
ctx.fillStyle = '#dddddd'; // 设置颜色
ctx.fillRect(10, 10, 130, 130); // 把(10,10)位置大小为130x130的矩形涂色
// 利用Path绘制复杂路径:
var path=new Path2D();
path.arc(75, 75, 50, 0, Math.PI*2, true);
path.moveTo(110,75);
ctx.strokeStyle = '#0000ff'; //颜色
ctx.stroke(path); //将路径画在canvas上
//绘制文本
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 2;
ctx.shadowColor = '#666666';
ctx.font = '24px Arial';
ctx.fillStyle = '#333333';
ctx.fillText('带阴影的文字', 20, 40);
最后:
对于JavaScript的基础学习就到这里了,这个系列只是简单的让大家对JS有一个快速的认知和掌握,具体在开发中还是要慢慢琢磨,希望对在做安卓开发又想拓展一下前端知识的你有一点点帮助。
至于前端后面的一些框架的学习使用的笔记,近期是没有写的打算了。
PS:
下一步会把数据结构和算法的知识捋一遍,并记录在我的博客中
如果对这方面内功知识有兴趣的,可以关注一下哈。
网友评论