express
- cnpm install express --save
- cnpm install nodemon --save ----------------------- 更改js后,無(wú)需重新node......
const express = require('express');
const app = express();
// 靜態(tài)資源
// http://localhost:3000/public/1.html能訪問(wèn)到靜態(tài)資源
app.use('/public', express.static('./public/'));
// 路由
app.get(function (req, res, next) { // 不寫第一個(gè)參數(shù)路徑時(shí)麸恍,相當(dāng)于'/'
console.log('1');
next();
res.send('ni hao');
});
app.get('/', function(req, res, next){ // next可以繼續(xù)往下匹配
console.log('1');
next();
res.send('ni hao');
});
app.get('/', function(rea,res){
console.log('2')
})
app.get('/teacher/:id', function(req,res){
res.send('teacher: ' + req.params.id + '沒(méi)有next時(shí),get方法争占,該路由匹配后,下面的路由就不會(huì)再匹配');
});
app.use('/teacher', function(req,res){
res.send('app.use能匹配/teacher/下的子文件夾蛾坯,而app.get post ...等不能')
})
app.use('/admin', function (req, res, next) {
// GET 'http://www.example.com/admin/new'
console.log(req.originalUrl); // '/admin/new'
console.log(req.baseUrl); // '/admin'
console.log(req.path); // '/new'
next();
});
app.get(/^\/student\/(\d{9,9})$/, function(req,res) { //可以使用正則
res.send('student:' + req.params[0]);
})
app.use(function(req,res){ // 都不匹配,就是404頁(yè)面
res.send('404')
})
app.listen(3000);
(一) JSONP
(1) 同源
所謂同源指的是三個(gè)相同
- 協(xié)議
- 域名
- 端口 --------------( http默認(rèn)端口80,https默認(rèn)端口443 )
(2) 如果是非同源,受到的限制的三種行為锄开?
- 無(wú)法讀取非同源網(wǎng)頁(yè)的 Cookie,LocalStorage称诗,IndexDB
- 無(wú)法接觸非同源網(wǎng)頁(yè)的 DOM
- 無(wú)法向非同源地址發(fā)送 AJAX 請(qǐng)求 ( 可以發(fā)送萍悴,當(dāng)瀏覽器會(huì)決絕接受響應(yīng) )
(3) jsonp -- ( JSON with Padding )
- JSONP(JSON with Padding)是數(shù)據(jù)格式JSON的一種“使用模式”
- 凡是擁有 ”src” 這個(gè)屬性的標(biāo)簽都擁有跨域的能力,如
<script>、<img>癣诱、<iframe>
- jsonp只能發(fā)送get請(qǐng)求
- 原理:
jsonp協(xié)議的一個(gè)要點(diǎn)就是允許用戶傳遞一個(gè)callback 參數(shù)給服務(wù)端任岸,然后服務(wù)端返回?cái)?shù)據(jù)時(shí)會(huì)將這個(gè)callback參數(shù)作為函數(shù)名來(lái)包裹住JSON數(shù)據(jù),這樣客戶端就可以隨意定制自己的函數(shù)來(lái)自動(dòng)處理返回?cái)?shù) 據(jù)了狡刘。 - script標(biāo)簽的src屬性格式:
script標(biāo)簽的src屬性格式
例如:
http://freegeoip.net/json/?callback=foo
- 服務(wù)端返回一個(gè)函數(shù),包裹住json:
JSONP看起來(lái)與JSON差不多困鸥,只不過(guò)是被包含在函數(shù)調(diào)用中的JSON
服務(wù)端返回一個(gè)函數(shù)嗅蔬,包裹住json
例如:
foo({ “name”: “Nicholas” });
注意:
這里的foo要和script中的src中的http://freegeoip.net/json/?callback=foo中的foo保持一致
- 客戶端完整請(qǐng)求
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script>
// 動(dòng)態(tài)插入 script 標(biāo)簽到 html 中
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.setAttribute('src', src);
document.getElementsByTagName('head')[0].appendChild(script);
}
// 獲取 jsonp 文件
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
// 執(zhí)行本地的 js 邏輯,這個(gè)要跟獲取到的 jsonp 文件的函數(shù)要一致
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
</script>
</head>
<body>
</body>
</html>
https://segmentfault.com/a/1190000012967320
(二) Element對(duì)象
Element對(duì)象對(duì)應(yīng)的是網(wǎng)頁(yè)的HTML元素疾就,每一個(gè)html元素在DOM樹(shù)上會(huì)轉(zhuǎn)化成Element節(jié)點(diǎn)對(duì)象
- 元素節(jié)點(diǎn)的 ( nodeType ) 屬性都是 ( 1 )
- Element.id ---------------------- 獲取元素節(jié)點(diǎn)的id屬性 (getElementById澜术,getAttribute() 等)
- Element.tagname ------------- 獲取元素的大寫標(biāo)簽名 (nodeName等)
- Element.draggable ----------- 元素節(jié)點(diǎn)是否可以被拖動(dòng),返回boolean猬腰,可讀寫
- Element.lang ------------------- 返回當(dāng)前元素的語(yǔ)言設(shè)置鸟废。該屬性可讀寫。
- Element.title -------------------- 用來(lái)讀寫當(dāng)前元素的 HTML 屬性title姑荷。該屬性通常用來(lái)指定盒延,鼠標(biāo)懸浮時(shí)彈出的文字提示框。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript">
window.onload = function() {
var x = document.querySelector('p'); ---------------------- 獲取p元素節(jié)點(diǎn)
var xx = document.getElementById('p'); -------------------- 獲取p元素節(jié)點(diǎn)
console.log(x,xx);
var y = x.id; -------------------------------------------- 獲取id屬性節(jié)點(diǎn)的屬性值
var yy = x.getAttribute('id'); ---------------------------- 獲取id屬性節(jié)點(diǎn)的屬性值
console.log(y, yy)
var z = x.tagName; ---------------------------- 獲取元素節(jié)點(diǎn)的標(biāo)簽名
var zz = x.nodeName; -------------------------- 獲取元素節(jié)點(diǎn)的標(biāo)簽名
console.log(z,zz)
x.draggable = false; -------------------------- 元素節(jié)點(diǎn)是否可拖動(dòng)
x.lang="zh-cn"; ------------------------------- 返回當(dāng)前元素的語(yǔ)言設(shè)置鼠冕。該屬性可讀寫添寺。
x.title = "hover時(shí),element.title作為提示內(nèi)容,pc上有效"; ----- hover時(shí)提示文字懈费,pc有效
}
</script>
</head>
<body>
<p id="p">p元素節(jié)點(diǎn)</p>
</body>
</html>
- Element.attributes ------------ 返回一個(gè)類似數(shù)組的對(duì)象,成員是當(dāng)前元素節(jié)點(diǎn)的所有屬性節(jié)點(diǎn)
- className屬性 --------------- 用來(lái)讀寫當(dāng)前元素節(jié)點(diǎn)的class屬性。它的值是一個(gè)字符串驻谆,每個(gè)class之間用空格分割脑又。
- classList屬性------------------- 返回一個(gè)類似數(shù)組的對(duì)象,當(dāng)前元素節(jié)點(diǎn)的每個(gè)class就是這個(gè)對(duì)象的一個(gè)成員泞边。
// HTML 代碼 <div class="one two three" id="myDiv"></div>
var div = document.getElementById('myDiv');
div.className --------------------------- element.className返回class屬性值 組成的字符串
// "one two three"
div.classList --------------------------- class屬性值組成的類數(shù)組對(duì)象
// {
// 0: "one"
// 1: "two"
// 2: "three"
// length: 3
// }
- classList對(duì)象有下列方法:
add():增加一個(gè) class该押。
remove():移除一個(gè) class。
contains():檢查當(dāng)前元素是否包含某個(gè) class繁堡。
toggle():將某個(gè) class 移入或移出當(dāng)前元素沈善。
item():返回指定索引位置的 class。
toString():將 class 的列表轉(zhuǎn)為字符串椭蹄。
-------------------------
var div = document.getElementById('myDiv');
div.classList.add('myCssClass');
div.classList.add('foo', 'bar');
div.classList.remove('myCssClass');
div.classList.toggle('myCssClass'); // 如果 myCssClass 不存在就加入闻牡,否則移除
div.classList.contains('myCssClass'); // 返回 true 或者 false
div.classList.item(0); // 返回第一個(gè) Class
div.classList.toString();
Element.innerHTML ---------- 所有子節(jié)點(diǎn)
- Element.innerHTML屬性返回一個(gè) ( 字符串 ) ,等同于該元素包含的所有 HTML 代碼绳矩。
- 該屬性可讀寫罩润,常用來(lái)設(shè)置某個(gè)節(jié)點(diǎn)的內(nèi)容。
- 它能改寫所有元素節(jié)點(diǎn)的內(nèi)容翼馆,包括<HTML>和<body>元素割以。
- 如果將innerHTML屬性設(shè)為空金度,等于刪除所有它包含的所有節(jié)點(diǎn)。
- 注意:
讀取屬性值的時(shí)候严沥,如果文本節(jié)點(diǎn)包含&猜极、小于號(hào)(<)和大于號(hào)(>),innerHTML屬性會(huì)將它們轉(zhuǎn)為實(shí)體形式&消玄、<跟伏、>
- 如果想得到原文,建議使用element.textContent屬性翩瓜。
- 寫入的時(shí)候受扳,如果插入的文本包含 HTML 標(biāo)簽,會(huì)被解析成為節(jié)點(diǎn)對(duì)象插入 DOM兔跌。注意勘高,如果文本之中含有<script>標(biāo)簽,雖然可以生成script節(jié)點(diǎn)坟桅,但是插入的代碼不會(huì)執(zhí)行华望。
Element.outerHTML ---------- 包括元素本身和所有子節(jié)點(diǎn)
Element.outerHTML屬性返回一個(gè)字符串,表示當(dāng)前元素節(jié)點(diǎn)的所有 HTML 代碼桦卒,包括該元素本身和所有子元素立美。
- outerHTML屬性是可讀寫的,對(duì)它進(jìn)行賦值方灾,等于替換掉當(dāng)前元素建蹄。
// HTML 代碼如下
// <div id="container"><div id="d">Hello</div></div>
var container = document.getElementById('container');
var d = document.getElementById('d');
container.firstChild.nodeName // "DIV"
d.nodeName // "DIV"
d.outerHTML = '<p>Hello</p>'; ------------------------- outerHTML可讀寫
container.firstChild.nodeName // "P"
d.nodeName // "DIV"
注意:
上面代碼中,變量d代表子節(jié)點(diǎn)裕偿,它的outerHTML屬性重新賦值以后洞慎,內(nèi)層的div元素就不存在了,被p元素替換了嘿棘。
但是劲腿,變量d依然指向原來(lái)的div元素,這表示被替換的DIV元素還存在于內(nèi)存中鸟妙。=谷恕!V馗浮;ㄍ帧!7课纭?罅伞!!4蟆5癖巍!1瞿取E!
- 注意前塔,如果一個(gè)節(jié)點(diǎn)沒(méi)有父節(jié)點(diǎn)贾陷,設(shè)置outerHTML屬性會(huì)報(bào)錯(cuò)。
Element.clientHeight
Element.clientWidth
- Element.clientHeight屬性返回一個(gè)整數(shù)值嘱根,表示元素節(jié)點(diǎn)的 CSS 高度(單位像素)
- 只對(duì)
塊級(jí)元素
生效,對(duì)于行內(nèi)元素返回0巷懈。 - 如果塊級(jí)元素沒(méi)有設(shè)置 CSS 高度该抒,則返回
實(shí)際高度
。 - 除了元素本身的高度顶燕,它還包括
padding
部分凑保,但是不包括border、margin涌攻。 - 如果有
水平滾動(dòng)條
欧引,還要減去水平滾動(dòng)條的高度。 - 這個(gè)值始終是
整數(shù)
恳谎,如果是小數(shù)會(huì)被四舍五入芝此。
document.documentElement ----------------------- 的clientHeight屬性,返回當(dāng)前視口的高度(即瀏覽器窗口的高度)因痛,等同于window.innerHeight屬性減去水平滾動(dòng)條的高度(如果有的話)婚苹。
document.body ----------------------------------------- 的高度則是網(wǎng)頁(yè)的實(shí)際高度。
一般來(lái)說(shuō)鸵膏,document.body.clientHeight大于document.documentElement.clientHeight膊升。
Element.clientLeft
Element.clientTop
- Element.clientLeft屬性等于元素節(jié)點(diǎn)左邊框(left border)的寬度(單位像素),不包括左側(cè)的padding和margin谭企。
- 如果沒(méi)有設(shè)置左邊框廓译,或者是行內(nèi)元素(display: inline),該屬性返回0债查。
- 該屬性總是返回整數(shù)值非区,如果是小數(shù),會(huì)四舍五入攀操。
- Element.clientTop屬性等于網(wǎng)頁(yè)元素頂部邊框的寬度(單位像素)院仿,其他特點(diǎn)都與clientTop相同。
Element.scrollHeight ------------ 當(dāng)前元素的總高度
Element.scrollWidth
-
Element.scrollHeight
屬性返回一個(gè)整數(shù)值
(小數(shù)會(huì)四舍五入),表示當(dāng)前元素的總高度(單位像素)
歹垫,包括溢出容器
剥汤、當(dāng)前不可見(jiàn)的部分
。 - 它包括padding排惨,但是不包括border吭敢、margin以及水平滾動(dòng)條的高度(如果有水平滾動(dòng)條的話)
- 還包括偽元素(::before或::after)的高度。
- Element.scrollWidth屬性表示當(dāng)前元素的總寬度(單位像素)暮芭,其他地方都與scrollHeight屬性類似鹿驼。
- 這兩個(gè)屬性只讀。
整張網(wǎng)頁(yè)的總高度可以從document.documentElement或document.body上讀取辕宏。
Element.scrollLeft
Element.scrollTop
- Element.scrollLeft屬性表示當(dāng)前元素的
水平滾動(dòng)條向右側(cè)滾動(dòng)的像素?cái)?shù)量
- Element.scrollTop屬性表示當(dāng)前元素的
垂直滾動(dòng)條向下滾動(dòng)的像素?cái)?shù)量
- 對(duì)于那些沒(méi)有滾動(dòng)條的網(wǎng)頁(yè)元素畜晰,這兩個(gè)屬性總是等于0
- 這兩個(gè)屬性都可讀寫,設(shè)置該屬性的值瑞筐,會(huì)導(dǎo)致瀏覽器將當(dāng)前元素自動(dòng)滾動(dòng)到相應(yīng)的位置凄鼻。
Element.offsetHeight
Element.offsetWidth
- Element.offsetHeight屬性返回一個(gè)整數(shù),表示元素的 CSS 垂直高度(單位像素)
- 包括元素本身的高度聚假、padding 和 border块蚌,以及水平滾動(dòng)條的高度(如果存在滾動(dòng)條)
- Element.offsetWidth屬性表示元素的 CSS 水平寬度(單位像素),其他都與Element.offsetHeight一致膘格。
Element.offsetLeft
Element.offsetTop
- Element.offsetLeft返回當(dāng)前元素左上角相對(duì)于Element.offsetParent節(jié)點(diǎn)的水平位移
- Element.offsetTop返回垂直位移峭范,單位為像素。通常瘪贱,這兩個(gè)值是指相對(duì)于父節(jié)點(diǎn)的位移
滾動(dòng)到頂部案列 vue
<template>
<div id="app">
<div class="top" v-if="buttonShow" v-on:click="goTop">回到頂部</div>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
buttonShow: false,
}
},
mounted() {
document.addEventListener('scroll', this.goScroll) ----- 頁(yè)面加載完成纱控,監(jiān)聽(tīng)scroll事件
},
methods: {
goScroll: function() {
const currentTop = document.documentElement.scrollTop || document.body.scrollTop;
const viewPort = document.documentElement.clientHeight || document.body.clientHeight;
console.log(currentTop, viewPort)
if (currentTop > viewPort/2) { ------------------------- 滾動(dòng)的距離和釋口距離比較
this.buttonShow = true
} else {
this.buttonShow = false;
}
},
goTop: function() {
console.log('aa');
let currentTop = document.documentElement.scrollTop || document.body.scrollTop;
const totalTime = 2000; ---------------------- 總時(shí)間
const frequent = 200; -------------------------- 頻率,多長(zhǎng)時(shí)間滾動(dòng)一次
const speed = currentTop/2000; ----------------- 滾動(dòng)的速度
const stepDistance = speed * frequent; --------- 一次滾動(dòng)的距離
let timer = setInterval(()=> {
if (currentTop<=0) { ------------------------- 距離小于0時(shí)菜秦,停止?jié)L動(dòng)
window.clearInterval(timer)
return;
}
currentTop = currentTop - stepDistance; ------ 當(dāng)前距離 = 初始距離 - 一次滾動(dòng)的距離
document.documentElement.scrollTop = currentTop; -------- 設(shè)置當(dāng)前距離滾動(dòng)頂部的距離
}, 20) ----------------------------------------- 20毫秒執(zhí)行一次以上操作
}
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.top {
background: yellow;
padding:20px 40px;
position: fixed;
bottom: 100px;
right: 10px;
}
</style>
滾動(dòng)到頂部案列 react
import React,{Component} from 'react';
export default class toTOP extends Component {
state = {
buttonShow: false
}
componentWillMount() {
window.addEventListener('scroll',this.onScroll) // 監(jiān)聽(tīng)滾動(dòng)事件
}
onScroll = () => {
var currentTop = document.documentElement.scrollTop || document.body.scrollTop; // 頂部到最頂部的距離
var viewPortHeight = document.documentElement.clientHeight || document.body.clientHeight; // 可視高度
if ( currentTop > viewPortHeight) { // 大于顯示按鈕
this.setState({
buttonShow:true
})
} else {
this.setState({ // 小于隱藏按鈕
buttonShow: false
})
}
}
goTop = () => {
var currentTop = document.documentElement.scrollTop || document.body.scrollTop;
var totalTimes = 200;
var speed = currentTop/totalTimes ;
var StepTime = 10;
var setpDistance = speed * StepTime;
var timer = window.setInterval(()=>{ // var itmer = setInterval()也可以其徙,不要window
if ( currentTop <=0 ) {
window.clearInterval(timer);
return;
}
currentTop = currentTop - setpDistance;
document.documentElement.scrollTop = currentTop;
document.body.scrollTop = currentTop;
},StepTime)
}
render() {
return (
<div >
<div>
回到頂部測(cè)試
</div>
<div
ref="button"
onClick={this.goTop}
style={
this.state.buttonShow
?
{
display:'inline-block',
border:'1px solid red',
background:'yellow',
padding:'10px 30px',
position:'fixed',
bottom:'60px',
right:'20px'
}
:
{
display:'none',
border:'1px solid red',
background:'yellow',
padding:'10px 30px',
position:'fixed',
bottom:'60px',
right:'20px'
}
}>
回到頂部
</div>
<div style={{padding:'20px 160px'}}>
年參演電視劇《與青春有關(guān)的日子》,開(kāi)始在影視圈嶄露頭角[1] 喷户。2005年拍攝古裝劇《錦衣衛(wèi)》唾那。2007年主演趙寶剛導(dǎo)演的青春劇《奮斗》;[2] 同年褪尝,主演首部電影《走著瞧》闹获。2008年主演滕華濤執(zhí)導(dǎo)的電視劇《蝸居》,飾演80后城市青年小貝河哑。[1] 2009年避诽,在電影《海洋天堂》中扮演自閉癥患者王大福;同年參演抗戰(zhàn)題材的電視劇《雪豹》[4] 璃谨。2011年沙庐,主演的電視劇《裸婚時(shí)代》在各大衛(wèi)視播出鲤妥;[5] 2011年-2012年連續(xù)2年獲得北京大學(xué)生電影節(jié)[6-7] 最受大學(xué)生歡迎男演員獎(jiǎng)。2012年拱雏,憑借電影《失戀33天》獲得第31屆大眾電影百花獎(jiǎng)最佳男主角獎(jiǎng)棉安;[8] 同年成立自己經(jīng)營(yíng)的北京君竹影視文化有限公司,并導(dǎo)演第一部影視作品《小爸爸》铸抑。2013年2月贡耽,主演的電影《西游·降魔篇》在全國(guó)上映。[9]
2014年3月28日鹊汛,主演的中韓合資文藝愛(ài)情片《我在路上最愛(ài)你》在全國(guó)上映蒲赂。2014年12月18日,在姜文執(zhí)導(dǎo)的動(dòng)作喜劇片《一步之遙》中扮演武七一角刁憋。[10] 2016年滥嘴,主演電視劇《少帥》,飾演張學(xué)良[11] 至耻;主演電視劇《剃刀邊緣》[12] 氏涩。7月15日導(dǎo)演的電影《陸垚知馬俐》上映。[13]
演藝事業(yè)外有梆,文章也參與公益慈善事業(yè),2010年成立大福自閉癥關(guān)愛(ài)基金意系。
2017年9月16日泥耀,憑借《陸垚知馬俐》獲得第31屆中國(guó)電影金雞獎(jiǎng)導(dǎo)演處女作獎(jiǎng)。[14]
關(guān)于你蛔添。就是因?yàn)槲业暮ε绿荡撸矣H眼看你走向她。我喜歡你是事實(shí)迎瞧,你有女朋友也是事實(shí)夸溶。我以為我不說(shuō)出口就會(huì)保持這樣的朋友關(guān)系,卻還是她趕了個(gè)巧凶硅,那應(yīng)該是個(gè)寒假缝裁,你有女朋友了,我還是聽(tīng)說(shuō)足绅,我那么愛(ài)捷绑,卻還是無(wú)果。于是我和她之間就莫名其妙的就多少有了敵人的感覺(jué)氢妈,或許就是別人口中的那樣粹污,世界上完全不相干的兩個(gè)女人,會(huì)因?yàn)橐粋€(gè)男人要么很友好首量,要么是仇恨壮吩。關(guān)于她我做不到友好进苍,但也不是仇恨,只是你選擇了她鸭叙,我就希望她好好愛(ài)你觉啊,照顧你,連我的份也一起愛(ài)了递雀。自愛(ài)上你的那天起柄延,思念便成了戒不掉的癮。你的一言一笑缀程,一顰一蹙搜吧,無(wú)不牽動(dòng)我的心,百千塵思杨凑,唯念一縷滤奈;萬(wàn)千紅顏,唯戀一人撩满。我愿意一生漂泊浪跡在你的故事里蜒程,甘愿為你鞍前馬后,馬首是瞻伺帘,即使你從未給我一句承諾昭躺,即使你從未給我半分愛(ài)情,依然無(wú)悔無(wú)怨伪嫁。
關(guān)于你领炫。一場(chǎng)高考,考散了我們张咳,畢業(yè)了會(huì)不會(huì)就是終生最后一見(jiàn)帝洪,很高興,我們不是脚猾。各奔東西了葱峡,你們繼續(xù)上了大學(xué),值得欣慰的是龙助,你們也是異地砰奕,這樣不能算是我心機(jī),只能說(shuō)是恰巧提鸟,你們的安排恰合我意脆淹。后來(lái)也有聽(tīng)說(shuō),她從她的城市去看你沽一,而那時(shí)的我能說(shuō)什么呢盖溺。她是真心愛(ài)你,這是事實(shí)铣缠。我也曾和閨蜜說(shuō)過(guò)烘嘱,一生至少該有一次昆禽,為了某個(gè)人而忘了自己,不求有結(jié)果蝇庭,不求同行醉鳖,不求曾經(jīng)擁有,甚至不求你愛(ài)我哮内,只求在我最美的年華里盗棵,遇到你。今生遇見(jiàn)你北发,我覺(jué)得是幸福的纹因,盡管這幸福交雜著萬(wàn)般痛苦。我也曾幻想著悄悄地去到你的學(xué)校琳拨,在某個(gè)陽(yáng)光明媚的下午瞭恰,在你去教室的路上和你來(lái)場(chǎng)偶遇,精心準(zhǔn)備的偶遇狱庇,惊畏。可是我還來(lái)不及去和你偶遇密任,你們就畢了業(yè)颜启。愛(ài)是種很玄的東西,說(shuō)不清浪讳,道不明缰盏,剪不斷,理還亂驻债。世上,有種愛(ài)明知沒(méi)有結(jié)果形葬,卻依然堅(jiān)守原地合呐,不舍離去,哪怕握不住你的一絲余溫笙以,依然選擇默默為你守候淌实。一路來(lái)去,心門只為你獨(dú)開(kāi)猖腕,山城只為你獨(dú)駐拆祈,白天只為你旖旎,黑夜只為你流連倘感。因?yàn)閻?ài)你放坏,哪怕心入住荒島,還是會(huì)以最深情的眼神老玛,看著你幸福淤年。
</div>
</div>
)
}
}
語(yǔ)句
語(yǔ)句 statement 是為了完成某種任務(wù)而進(jìn)行的操作
- 語(yǔ)句以分號(hào)結(jié)尾钧敞,一個(gè)分號(hào)就表示一個(gè)語(yǔ)句結(jié)束
- 多個(gè)語(yǔ)句,可以寫在一行內(nèi)
- 分號(hào)前面可以沒(méi)有任何內(nèi)容麸粮,js將其視為空語(yǔ)句
表達(dá)式
表達(dá)式 expression 為了得到返回值的計(jì)算式
- 凡是預(yù)期為值得地方溉苛,都可以使用表達(dá)式
表達(dá)式和語(yǔ)句的區(qū)別
- 語(yǔ)句是為了進(jìn)行某種操作,一般不需要返回值
- 表達(dá)式式為了得到返回值弄诲,一定有返回值
表達(dá)式和語(yǔ)句總結(jié):
(1) 語(yǔ)句是為了完成某種任務(wù)進(jìn)行得操作愚战,一般不需要返回值
(2) 語(yǔ)句以分號(hào)結(jié)尾,分號(hào)前面可以沒(méi)有任何內(nèi)容齐遵,是空語(yǔ)句
(3) 多個(gè)語(yǔ)句可以寫在一行內(nèi)
(4) 表達(dá)式是為了得到返回值得計(jì)算值寂玲,一定有返回值,凡是預(yù)期為值的地方洛搀,都可以使用表達(dá)式
var a = 1 + 3 ; var b = 'abc'; ------------- 語(yǔ)句以分號(hào)結(jié)尾敢茁,兩個(gè)語(yǔ)句可以寫在一行內(nèi)
;;; ----------------------------------------- 空語(yǔ)句,分號(hào)前面可以沒(méi)有任何內(nèi)容留美,js視其為空語(yǔ)句
1+3 在等號(hào)右邊彰檬,預(yù)期是個(gè)值,所以可以使用表達(dá)式(為了得到返回值的計(jì)算式)
變量
變量是對(duì)值得具名引用
- 變量就是為值取名谎砾,-------引用這個(gè)名字逢倍,就是引用這個(gè)值
- 變量名:變量的名字就是變量名
- 變量名區(qū)分大小寫 ( A和a是兩個(gè)不同的變量 )
- 如果只是聲明變量,而沒(méi)有賦值景图,那么變量的值是 undefined
- 如果變量賦值的時(shí)候较雕,忘了寫var命令,這條語(yǔ)句也是有效的挚币。
- 可以在同一條var命令中聲明多個(gè)變量亮蒋。
- js是動(dòng)態(tài)語(yǔ)言,變量的類型沒(méi)有限制妆毕,變量可以隨時(shí)更改類型
- 如果使用var重新聲明一個(gè)已經(jīng)存在的變量慎玖,是無(wú)效的,但是笛粘,如果第二次聲明的時(shí)候還進(jìn)行了賦值趁怔,則會(huì)覆蓋掉前面的值。
變量提升
js引擎的工作方式:先解析代碼薪前,獲取所有被聲明的變量润努,再一行一行的執(zhí)行,造成造成的結(jié)果就是所有變量的聲明語(yǔ)句示括,都會(huì)被提升到代碼頭部铺浇,這就叫做 ----- 代碼提升hoisting -----
console.log(a);
var a = 1; --------------------- 變量提升,變量的聲明語(yǔ)句會(huì)被提升到代碼頭部垛膝,注意不包括賦值語(yǔ)句
等同于
var a;
console.log(a); -------------------- a是undifined随抠,不會(huì)報(bào)錯(cuò)
a = 1;
標(biāo)識(shí)符
標(biāo)識(shí)符identifier: 用來(lái)識(shí)別各種值得合法名稱
- 最常見(jiàn)的表示符裁着,------變量名和函數(shù)名
- 標(biāo)識(shí)符的命名規(guī)則:
第一個(gè)字符,可以是任意 Unicode 字母(包括英文字母和其他語(yǔ)言的字母)拱她,以及美元符號(hào)($)和下劃線(_)二驰。
第二個(gè)字符及后面的字符,除了 Unicode 字母秉沼、美元符號(hào)和下劃線桶雀,還可以用數(shù)字0-9。
第一個(gè)字符:字母唬复,$矗积,下劃線
第二個(gè)字符:字母,數(shù)字敞咧,$棘捣,下劃線
- 中文是合法的標(biāo)識(shí)符,可以用作變量名休建。
注釋
- 一種是單行注釋乍恐,用
//
起頭; - 另一種是多行注釋测砂,放在
/*
和*/
之間茵烈。
區(qū)塊
JavaScript 使用大括號(hào),將多個(gè)相關(guān)的語(yǔ)句組合在一起砌些,稱為“區(qū)塊”(block)呜投。
- 區(qū)塊:大括號(hào)包裹的多個(gè)語(yǔ)句
- 對(duì)于var命令來(lái)說(shuō),區(qū)塊不構(gòu)成單獨(dú)的作用域scop存璃,與不使用區(qū)塊沒(méi)有任何區(qū)別
- 單獨(dú)使用區(qū)塊不常見(jiàn)仑荐,區(qū)塊一般用來(lái)構(gòu)成復(fù)雜的語(yǔ)法結(jié)構(gòu),如for,while,if,funcion等
{
var a = 1;
}
a // 1
if結(jié)構(gòu)
if (m === 3) ------------------------- 只有在m等于3時(shí)纵东,才會(huì)將其值加上1
m = m + 1; -------------------------- 只有一個(gè)語(yǔ)句時(shí)粘招,可以不用 { }
break語(yǔ)句和continue語(yǔ)句
- break語(yǔ)句用于跳出代碼塊或循環(huán)。
- continue語(yǔ)句用于立即終止本輪循環(huán)篮迎,返回循環(huán)結(jié)構(gòu)的頭部男图,開(kāi)始下一輪循環(huán)示姿。
數(shù)據(jù)類型
number甜橱,string,boolean栈戳,null岂傲,undefined,object子檀,symbol
如何確定一個(gè)值是什么類型 ( 三種方法 )
- typeof ---------------------------------- 有6種返回值
- instanceof ----------------------------- 主要用于對(duì)象镊掖,數(shù)組的區(qū)分
- object.prototype.toString
typeof
- typeof返回的是一個(gè)字符串乃戈,注意是一個(gè)字符串
- 數(shù)值、字符串亩进、布爾值分別返回number症虑、string、boolean归薛。
- 函數(shù)返回function
- undefined返回undefined
- 對(duì)象返回object
- 數(shù)組返回object
- null返回object
typeof是個(gè)一元運(yùn)算符谍憔,運(yùn)算時(shí)具有較高的優(yōu)先級(jí)
(1) es5有6種數(shù)據(jù)類型, typeof返回也是6種類型
---------- es5的6種數(shù)據(jù)類型:number, string, boolean, undefined, null, object
---------- typeof返回的6種類型:number, string, boolean, undefined, object, function
(2) typeof無(wú)法區(qū)分?jǐn)?shù)組和對(duì)象
----------- 數(shù)組和對(duì)象可以通過(guò) instanceof 來(lái)區(qū)分
var o = {};
var a = [];
o instanceof Array // false
a instanceof Array // true
(3) Number
Number(null) ------------------------- 0
Number(undefined) -------------------- NaN
Number('') --------------------------- 0
Number(true) ------------------------- 0
5 + null ----------------------------- 5
5 + undefined ------------------------ NaN
(4) typeof NaN ----------------------- 'number'
注意 typeof 返回的是一個(gè)字符串
NaN不等于任何值主籍,包括自身
數(shù)組的indexOf方法內(nèi)部使用的是嚴(yán)格相等運(yùn)算符习贫,所以該方法對(duì)NaN不成立。
[NaN].indexOf(NaN) // -1
(5) typeof是一元運(yùn)算符千元,具有較高的運(yùn)算優(yōu)先級(jí)
typeof 1 !== 'undefined'
運(yùn)算順序是:
1. typeof 1 ----------------------------- 結(jié)果是 number
2. 'number' !== 'undefined' -------------- 結(jié)果是true
typeof ( 1 !== 'number' ); ----------------------- 結(jié)果是 'boolean'
typeof 1 !== 'number' ----------------------- 結(jié)果是 false
與數(shù)值相關(guān)的全局方法
parseInt(字符串苫昌,值的進(jìn)制)
parseInt() 用于將 ( 字符串 ) 轉(zhuǎn)化為 ( 整數(shù) )
- 如果字符串頭部有空格,空格會(huì)被自動(dòng)去除幸海。
- 如果parseInt的參數(shù)不是字符串祟身,則會(huì)先轉(zhuǎn)為字符串再轉(zhuǎn)換。
- 字符串轉(zhuǎn)為整數(shù)的時(shí)候涕烧,是一個(gè)個(gè)字符依次轉(zhuǎn)換月而,如果遇到不能轉(zhuǎn)為數(shù)字的字符,就不再進(jìn)行下去议纯,返回已經(jīng)轉(zhuǎn)好的部分父款。
- 如果字符串的第一個(gè)字符不能轉(zhuǎn)化為數(shù)字(后面跟著數(shù)字的正負(fù)號(hào)除外),返回NaN瞻凤。
所以憨攒,parseInt的返回值只有兩種可能,要么是一個(gè)十進(jìn)制整數(shù)阀参,要么是NaN肝集。
- 如果字符串以0開(kāi)頭,將其按照10進(jìn)制解析蛛壳。
- 參數(shù):
parseInt方法還可以接受第二個(gè)參數(shù)(2到36之間)杏瞻,表示被解析的值的進(jìn)制,返回該值對(duì)應(yīng)的十進(jìn)制數(shù)衙荐。 - 如果第二個(gè)參數(shù)是0捞挥、undefined和null,則直接忽略
parseInt(1.23) // 1
// 等同于
parseInt('1.23') // 1
// 也等同于
parseInt(' 1.23') // 1
參數(shù)
parseInt('1000', 2) -------------------- 表示將2進(jìn)制的字符串1000忧吟,轉(zhuǎn)換成十進(jìn)制整數(shù)
parseFloat()
- 如果參數(shù)不是字符串砌函,或者字符串的第一個(gè)字符不能轉(zhuǎn)化為浮點(diǎn)數(shù),則返回NaN。
- 區(qū)別Number()函數(shù)
parseFloat(true) // NaN
Number(true) // 1
parseFloat(null) // NaN
Number(null) // 0
parseFloat('') // NaN
Number('') // 0
parseFloat('123.45#') // 123.45
Number('123.45#') // NaN
isNaN()
isNaN方法可以用來(lái)判斷一個(gè)值是否為NaN
- isNaN只對(duì)數(shù)值有效讹俊,如果傳入其他值垦沉,會(huì)被先轉(zhuǎn)成數(shù)值。
- 比如仍劈,傳入字符串的時(shí)候厕倍,字符串會(huì)被先轉(zhuǎn)成NaN,所以最后返回true贩疙。
也就是說(shuō)绑青,isNaN為true的值,有可能不是NaN屋群,而是一個(gè)字符串闸婴。
- 出于同樣的原因,對(duì)于對(duì)象和數(shù)組芍躏,isNaN也返回true岔乔。
- 但是纯路,對(duì)于空數(shù)組和只有一個(gè)數(shù)值成員的數(shù)組,isNaN返回false。
isNaN('Hello') // true
// 相當(dāng)于
isNaN(Number('Hello')) // true ---------------------------- Number('hello')值是NaN
class類
- 類的constructor()方法就是構(gòu)造函數(shù)
- 定義類的方法的時(shí)候荐捻,前面不需要加 ( function ) 關(guān)鍵字
- 類的方法之間岂津,不需要 ( 逗號(hào) ) 分隔盖袭,加了逗號(hào)會(huì)報(bào)錯(cuò)
-
es6的類怠晴,可以看作是構(gòu)造函數(shù)的另一種寫法,類的數(shù)據(jù)類型是'function'临燃,類本身就指向構(gòu)造函數(shù)睛驳,使用時(shí),也是通過(guò)new命令生成實(shí)例膜廊,類的所有方法都是定義在類的prototype屬性上面
------------------------- 重要 - 類的內(nèi)部所有定義的方法乏沸,都是不可枚舉的(non-enumerable)。
- 類的屬性名爪瓜,可以采用表達(dá)式蹬跃。( 為了得到返回值的計(jì)算式是 表達(dá)式 )
- 類和模塊的內(nèi)部,默認(rèn)就是嚴(yán)格模式铆铆,所以不需要使用use strict指定運(yùn)行模式蝶缀。
- 實(shí)例的屬性除非顯式定義在自身,即this對(duì)象上薄货,否則都是定義在原型上
- 類的實(shí)例可以共享一個(gè)原型對(duì)象翁都,原型鏈繼承
class Point {
doStuff() {
console.log('stuff');
}
}
var b = new Point ();
b.doStuff() // "stuff"
typeof Point // "function"
Point === Point.prototype.constructor // true
// 等同于
Point.prototype = {
doStuff() {},
};
constructor方法
一個(gè)類必須有constructor方法,如果沒(méi)有顯式定義菲驴,一個(gè)空的constructor方法將會(huì)被默認(rèn)添加
class表達(dá)式
與函數(shù)一樣荐吵,類也可以使用表達(dá)式的形式定義
類不存在變量提升
class靜態(tài)方法
類相當(dāng)于實(shí)例的原型骑冗,所有在類中定義的方法赊瞬,都會(huì)被實(shí)例所繼承
- 如果在類的方法前加上 static 關(guān)鍵字先煎,就表示該方法不會(huì)被實(shí)例所繼承,而是直接通過(guò)類來(lái)調(diào)用巧涧,這就成為靜態(tài)方法
- 靜態(tài)方法: 在方法前加上 static 關(guān)鍵字薯蝎,表示該方法不會(huì)被類的實(shí)例所繼承,而是直接通過(guò)類來(lái)調(diào)用
注意谤绳,如果靜態(tài)方法包含this關(guān)鍵字占锯,這個(gè)this指的是類,而不是實(shí)例缩筛。
- 靜態(tài)方法可以和非靜態(tài)方法重名
- 父類的靜態(tài)方法消略,可以被子類繼承。
- 靜態(tài)方法也是可以從super對(duì)象上調(diào)用的瞎抛。
class AAA{
static go() {
console.log('aaaa')
}
};
const BBB = new AAA();
BBB.go() --------------------- Uncaught TypeError: BBB.go is not a function
AAA.go() --------------------- aaaa
解析:
(1) 在類中定義的方法艺演,都會(huì)被類的實(shí)例所繼承
(2) 但是在方法前加上 static 關(guān)鍵字后,該方法是靜態(tài)方法桐臊,不會(huì)被實(shí)例所繼承胎撤,而是直接通過(guò)類本身調(diào)用
class Foo {
static bar () { -------------------------- 靜態(tài)方法中的this指的是類,而不是實(shí)例
this.baz(); ---------------------------- 靜態(tài)方法不被實(shí)例所繼承
}
static baz () {
console.log('hello');
}
baz () { --------------------------------- 靜態(tài)方法可以和非靜態(tài)方法重名
console.log('world'); ------------------ 非靜態(tài)方法断凶,被實(shí)例所繼承
}
}
Foo.bar() // hello
class Bar extends Foo { ------------------- 父類得靜態(tài)方法伤提,能被子類所繼承
}
Bar.bar() // 'hello'
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
static classMethod() {
return super.classMethod() + ', too'; ----------------- super在靜態(tài)方法中表示父類
}
}
Bar.classMethod() // "hello, too"
class的靜態(tài)屬性和實(shí)例屬性
靜態(tài)屬性指的是class本身的屬性,而不是定義在實(shí)例對(duì)象上的 ( this ) 屬性
- 靜態(tài)屬性
class Foo {
}
Foo.prop = 1;
Foo.prop // 1
提案新寫法:
class MyClass {
static myStaticProp = 42; ---------------------------- 靜態(tài)屬性
constructor() {
console.log(MyClass.myStaticProp); // 42
}
}
- 實(shí)例屬性
以前认烁,定義實(shí)例屬性肿男,只能寫在類的constructor方法里面。
有了新的寫法以后却嗡,可以不在constructor方法里面定義次伶。
class ReactCounter extends React.Component {
constructor(props) {
super(props);
this.state = { --------------------- 在類的constructor構(gòu)造函數(shù)中,定義實(shí)例屬性
count: 0
};
}
}
class ReactCounter extends React.Component {
state = {
count: 0
};
}
- 靜態(tài)屬性和實(shí)例屬性總結(jié)
class MyClass {
myProp = 42; --------------------------------- 類的實(shí)例屬性
static myStaticProp = 42; ------------------------ 類的靜態(tài)屬性
static constructor() {
console.log(this.myProp); // 42
console.log(MyClass.myStaticProp); // 42
}
}
class繼承
- class通過(guò) extends 關(guān)鍵字實(shí)現(xiàn)繼承
- 子類必須在constructor中調(diào)用super方法稽穆,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)冠王。因?yàn)樽宇惖淖约旱膖his對(duì)象,必須通過(guò)父類的構(gòu)造函數(shù)完成塑造舌镶,得到與父類同樣是實(shí)例屬性和方法柱彻,然后對(duì)其加工,得到子類自己的實(shí)例屬性和方法餐胀。
- 如果不調(diào)用super方法哟楷,就得不到this對(duì)象
- 在子類的constructor中,只有先調(diào)用 super 方法后否灾,才能使用 this 關(guān)鍵字
- 父類的靜態(tài)方法卖擅,被子類所繼承,但是不被實(shí)例所繼承
- Object.getPrototypeOf方法可以用來(lái)從子類上獲取父類。
super關(guān)鍵字
super關(guān)鍵字惩阶,可以當(dāng)函數(shù)挎狸,也可以當(dāng)對(duì)象
super作為函數(shù)
super作為函數(shù)調(diào)用時(shí),代表父類的構(gòu)造函數(shù)
super為函數(shù)時(shí)断楷,雖然代表父類的構(gòu)造函數(shù)锨匆,但是 ( 返回 ) 的是 ( 子類的實(shí)例 )!6病?致唷!舞痰!
- super為函數(shù)時(shí)土榴,只能用在子類的 constructor 中,用在其他地方會(huì)報(bào)錯(cuò)
super作為對(duì)象
super作為對(duì)象响牛,在普通方法中指父類的原型對(duì)象
super作為對(duì)象時(shí)鞭衩,用在普通方法中表示父類的原型對(duì)象,用在靜態(tài)方法中娃善,表示父類论衍。
class A {
p() { ----------------------- 類的實(shí)例方法,是定義在類的原型上的
return 2;
}
}
class B extends A {
constructor() {
super();
console.log(super.p()); -------- super作為對(duì)象聚磺,在普通方法中坯台,表示父類的原型對(duì)象 //結(jié)果是2
}
}
let b = new B();
這里需要注意,由于super指向父類的原型對(duì)象瘫寝,所以定義在父類實(shí)例上的方法或?qū)傩匝牙伲菬o(wú)法通過(guò)super調(diào)用的。
class A {
constructor() {
this.p = 2;
}
}
class B extends A {
get m() {
return super.p;
} ----------------super作為對(duì)象焕阿,表示父類的原型對(duì)象咪啡,所以定義在父類實(shí)例上的屬性和方法無(wú)法通過(guò)super調(diào)用
}
let b = new B();
b.m // undefined
- 如果方法和屬性定義在父類的原型對(duì)象上,super可以取到
class A {}
A.prototype.x = 2;
class B extends A {
constructor() {
super();
console.log(super.x) // 2
}
}
let b = new B();
ES6規(guī)定暮屡,在子類普通方法中撤摸,通過(guò)super調(diào)用父類的原型對(duì)象上的方法(父類的方法)時(shí),方法內(nèi)部的this褒纲,指向 ( 當(dāng)前 ) 的 ( 子類實(shí)例 ) !!!!!!!!!!!
class A {
constructor() {
this.x = 1;
}
print() {
console.log(this.x);----------(3) this指類的實(shí)例
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
m() {
super.print();--(2) 指A中的print()准夷,但是方法中的this,指向當(dāng)前子類實(shí)例莺掠,this指函數(shù)調(diào)用時(shí)所在的對(duì)象
}
}
let b = new B();
b.m() // 2 ---------------------(1) b.m()即B中的m()
- 由于this指向子類實(shí)例衫嵌,所以如果通過(guò)super對(duì)某個(gè)屬性賦值,這時(shí)super就是this彻秆,賦值的屬性會(huì)變成子類實(shí)例的屬性楔绞。
class A {
constructor() {
this.x = 1;
}
}
class B extends A {
constructor() {
super();
this.x = 2;
super.x = 3; ----------------------- 通過(guò)super對(duì)某個(gè)屬性賦值结闸,super.x === this.x
console.log(super.x); --------------- 讀取super.x的時(shí)候,讀的是A.prototype.x酒朵,所以返回undefined
console.log(this.x); // 3
}
}
let b = new B();
super作為對(duì)象桦锄,在靜態(tài)方法中,指父類
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg); ---------- 父類原型上的方法
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);--------------- super在靜態(tài)方法中表示父類耻讽,父類直接調(diào)用,父類的靜態(tài)方法
}
myMethod(msg) {
super.myMethod(msg); -------------- 原型鏈上的方法帕棉,super在普通方法中针肥,表示父類的原型
}
}
Child.myMethod(1); // static 1 ------------ 通過(guò)類直接調(diào)用,靜態(tài)方法
var child = new Child();
child.myMethod(2); // instance 2 --------- 實(shí)例上調(diào)用香伴,原型鏈方法
在子類的靜態(tài)方法中通過(guò)super調(diào)用父類的方法時(shí)慰枕,方法內(nèi)部的this指向當(dāng)前的子類,而不是子類的實(shí)例即纲。
class A {
constructor() {
this.x = 1;
}
static print() {
console.log(this.x); ---------------------------- this指向B具帮, B.x時(shí)B的靜態(tài)屬性
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
static m() {
super.print();
}
}
B.x = 3; -------------------------------------------- B的靜態(tài)屬性x
B.m() // 3 -------------------------------------------- 結(jié)果是3
解析:
靜態(tài)方法B.m里面,super.print指向父類的靜態(tài)方法print()低斋。這個(gè)方法里面的this指向的是B蜂厅,而不是B的實(shí)例。
- 注意膊畴,使用super的時(shí)候掘猿,必須顯式指定是作為函數(shù)、還是作為對(duì)象使用唇跨,否則會(huì)報(bào)錯(cuò)稠通。
類的prototype屬性和__ proto__屬性
Class 作為構(gòu)造函數(shù)的語(yǔ)法糖,同時(shí)有prototype屬性和 __ proto__屬性买猖,因此同時(shí)存在兩條繼承鏈改橘。
(1)子類的__ proto__屬性,表示構(gòu)造函數(shù)的繼承玉控,總是指向父類飞主。
(2)子類prototype屬性的__ proto__屬性,表示方法的繼承高诺,總是指向父類的prototype屬性既棺。
lass A {
}
class B extends A {
}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
解析:
(1) 子類.__proto__ === 父類
(2) 子類.prototype.__proto__ === 父類.prototype
- 這樣的結(jié)果是因?yàn)椋惖睦^承是按照下面的模式實(shí)現(xiàn)的
class A {
}
class B {
}
// B 的實(shí)例繼承 A 的實(shí)例
Object.setPrototypeOf(B.prototype, A.prototype);---------> B.prototype.__proto__ === A.prototype
// B 繼承 A 的靜態(tài)屬性
Object.setPrototypeOf(B, A); --------------------------> B.__proto__ === A
const b = new B();
- 這兩條繼承鏈懒叛,可以這樣理解:
(1) 作為一個(gè)對(duì)象丸冕,子類(B)的原型(__ proto__屬性)是父類(A);
(2) 作為一個(gè)構(gòu)造函數(shù)薛窥,子類(B)的原型對(duì)象(prototype屬性)是父類的原型對(duì)象(prototype屬性)的實(shí)例胖烛。
Object.create(A.prototype); --------------------- 以A.prototype為原型眼姐,創(chuàng)建實(shí)例對(duì)象
// 等同于
B.prototype.__proto__ = A.prototype;
- extends關(guān)鍵字后面可以跟多種類型的值。
class B extends A {
}
上面代碼的A佩番,只要是一個(gè)有prototype屬性的函數(shù)众旗,就能被B繼承。
由于函數(shù)都有prototype屬性(除了Function.prototype函數(shù))趟畏,因此A可以是任意函數(shù)贡歧。
regexp
字符串有四種與正則有關(guān):
match(),search()赋秀,replace()利朵,split()
- regular expression 正則表達(dá)式
- 新建正則表達(dá)式有兩種方法:
- 字面量: 以斜杠表示開(kāi)始和結(jié)束
- RegExp構(gòu)造函數(shù)
- 字面量方式和RegExp方式的區(qū)別:
- 字面量--------------------- 編譯時(shí)新建,效率高
- new Regexp() ----------- 運(yùn)行時(shí)新建猎莲,效率低
var regex = /xyz/; ---------------------------------- 字面量方式绍弟,以斜杠表示開(kāi)始和結(jié)束
var regex = new RegExp('xyz'); ----------------------- RegExp構(gòu)造函數(shù)
- RegExp()可以有兩個(gè)參數(shù),第一個(gè)是正則字符串著洼,第二個(gè)表示修飾符
var regex = new RegExp('xyz', 'i'); ---------------- i 是 ignoreCase 的縮寫樟遣, 表示忽略大小寫
// 等價(jià)于
var regex = /xyz/i;
正則對(duì)象的實(shí)例屬性
- RegExp.prototype.ignoreCase:返回一個(gè)布爾值,表示是否設(shè)置了 ( i ) 修飾符身笤。
- RegExp.prototype.global:返回一個(gè)布爾值豹悬,表示是否設(shè)置了 ( g ) 修飾符。
- RegExp.prototype.multiline:返回一個(gè)布爾值液荸,表示是否設(shè)置了 ( m ) 修飾符屿衅。
上面三個(gè)屬性都是只讀的。 - RegExp.prototype.lastIndex:返回一個(gè)數(shù)值莹弊,表示下一次開(kāi)始搜索的位置涤久。
該屬性可讀寫,但是只在進(jìn)行連續(xù)搜索時(shí)有意義忍弛,詳細(xì)介紹請(qǐng)看后文响迂。
- RegExp.prototype.source:返回正則表達(dá)式的字符串形式(不包括反斜杠),該屬性只讀细疚。
var r = /abc/igm;
r.ignoreCase // true
r.global // true
r.multiline // true
r.lastIndex -------------------------- 0 lastIndex返回一個(gè)數(shù)值蔗彤,表示下一次開(kāi)始搜索的位置
r.source --------------------------- "abc" source返回正則表達(dá)式的字符串形式,只讀
正則表示式的實(shí)例方法
RegExp.prototype.test()
- 正則實(shí)例對(duì)象的test方法返回一個(gè)布爾值疯兼,表示當(dāng)前模式是否能匹配參數(shù)字符串
- 如果正則表達(dá)式帶有g(shù)修飾符然遏,則每一次test方法都從上一次結(jié)束的位置開(kāi)始向后匹配。
- 帶有g(shù)修飾符時(shí)吧彪,可以通過(guò)正則對(duì)象的lastIndex屬性指定開(kāi)始搜索的位置待侵。
var r = /x/g;
var s = '_x_x';
r.lastIndex // 0 ------------------- 從0開(kāi)始匹配
r.test(s) // true ------------------ 匹配
r.lastIndex // 2 ------------------- 下一次從2位置開(kāi)始匹配
r.test(s) // true ------------------ 匹配
r.lastIndex // 4
r.test(s) // false
- 如果正則模式是一個(gè)空字符串,則匹配所有字符串姨裸。
new RegExp('').test('abc')
// true
RegExp.prototype.exec()
1. exec()匹配成功返回?cái)?shù)組秧倾,匹配失敗返回null
2. 數(shù)組成員包括怨酝,整個(gè)匹配成功的字符串,input那先,index
3. 正則帶有括號(hào)农猬,數(shù)組有多個(gè)成員,第一個(gè)是整個(gè)匹配售淡,第二個(gè)是第一個(gè)括號(hào)的匹配結(jié)果斤葱,第三個(gè)成員是第二個(gè)括號(hào)匹配的結(jié)果
4. 正則帶有g(shù)修飾符,則exec()可以執(zhí)行多次
正則實(shí)例對(duì)象的exec方法揖闸,用來(lái)返回匹配結(jié)果揍堕。如果發(fā)現(xiàn)匹配,就返回一個(gè)數(shù)組楔壤,成員是匹配成功的子字符串鹤啡,否則返回null惯驼。
- 匹配成功蹲嚣,
exec()返回?cái)?shù)組
,成員是匹配成功的子字符串
- 匹配失敗祟牲,exec()返回null
- exec方法的返回?cái)?shù)組還包含以下兩個(gè)屬性:
- input:整個(gè)原字符串隙畜。
- index:整個(gè)模式匹配成功的開(kāi)始位置(從0開(kāi)始計(jì)數(shù))。
- 如果正則表示式包含圓括號(hào)(即含有“組匹配”)说贝,則返回的數(shù)組會(huì)包括多個(gè)成員议惰。
- 第一個(gè)成員是整個(gè)匹配成功的結(jié)果,
- 后面的成員就是圓括號(hào)對(duì)應(yīng)的匹配成功的組乡恕。
也就是說(shuō)言询,
第二個(gè)成員對(duì)應(yīng)第一個(gè)括號(hào),
第三個(gè)成員對(duì)應(yīng)第二個(gè)括號(hào)傲宜,
以此類推运杭。整個(gè)數(shù)組的length屬性等于組匹配的數(shù)量再加1。
var a = /a(a)(b)/; ---------------------- 如果正則帶有括號(hào)函卒,exec()返回的數(shù)組就包括多個(gè)成員
var b = 'aababacad';
var d = a.exec(b);
console.log(d)
結(jié)果是: ["aab", "a", "b", index: 0, input: "aababacad"]
第一個(gè)成員: 整個(gè)匹配的結(jié)果
第二個(gè)成員: 第一個(gè)括號(hào)匹配的結(jié)果
第三個(gè)成員: 第二個(gè)括號(hào)匹配的結(jié)果
- 如果正則表達(dá)式加上g修飾符辆憔,則可以使用多次exec方法,下一次搜索的位置從上一次匹配成功結(jié)束的位置開(kāi)始报嵌。
var reg = /a/g;
var str = 'abc_abc_abc'
var r1 = reg.exec(str);
r1 // ["a"]
r1.index // 0
reg.lastIndex // 1
var r2 = reg.exec(str);
r2 // ["a"]
r2.index // 4
reg.lastIndex // 5
var r3 = reg.exec(str);
r3 // ["a"]
r3.index // 8
reg.lastIndex // 9
var r4 = reg.exec(str);
r4 // null
reg.lastIndex // 0
String.prototype.match()
- 匹配成功返回一個(gè)數(shù)組虱咧,匹配失敗返回null。
- 當(dāng)正則帶有g(shù)修飾符時(shí)锚国,返回所有匹配成功的結(jié)果
- 設(shè)置正則表達(dá)式的lastIndex屬性腕巡,對(duì)match方法無(wú)效,匹配總是從字符串的第一個(gè)字符開(kāi)始血筑。
重要
var s = 'abba';
var r = /a/g;
s.match(r) // ["a", "a"] ----------------- string.match(正則帶有g(shù)修飾符時(shí))逸雹,返回所有匹配成功的結(jié)果
r.exec(s) // ["a"] ---------------------- exec()返回匹配成功的子字符串
注意:
1. exec()和match()的區(qū)別: 成功時(shí)营搅,都返回?cái)?shù)組,但match()正則表達(dá)式參數(shù)中有g(shù)修飾符梆砸,返回所有匹配成功的結(jié)果
2. 設(shè)則正則的lastIndex屬性转质,對(duì)match()無(wú)效,match()總是從第一個(gè)字符開(kāi)始匹配
var r = /a|b/g;
r.lastIndex = 7;
'xaxb'.match(r) // ['a', 'b']
r.lastIndex // 0
String.prototype.search()
--------------- 返回正則匹配結(jié)果在字符串中的位置
-
區(qū)別 indexOf 方法:
-
search()的參數(shù)必須是正則表達(dá)式帖世,而indexOf()的參數(shù)只是普通字符串, indexOf效率更高
- 字符串對(duì)象的search方法休蟹,返回第一個(gè)滿足條件的匹配結(jié)果在整個(gè)字符串中的位置。
- 如果沒(méi)有任何匹配日矫,則返回-1赂弓。
String.prototype.replace()
- 字符串對(duì)象的replace方法可以替換匹配的值。它接受兩個(gè)參數(shù)哪轿,第一個(gè)是正則表達(dá)式盈魁,表示搜索模式,第二個(gè)是替換的內(nèi)容窃诉。
- 正則表達(dá)式如果不加g修飾符杨耙,就替換第一個(gè)匹配成功的值,否則替換所有匹配成功的值飘痛。
'aaa'.replace('a', 'b') // "baa"
'aaa'.replace(/a/, 'b') // "baa"
'aaa'.replace(/a/g, 'b') // "bbb" --------------- 正則帶有g(shù)修飾符珊膜,替換所有匹配成功的值
- replace方法的一個(gè)應(yīng)用,就是消除字符串首尾兩端的空格宣脉。
String.prototype.split()
- 字符串對(duì)象的split方法按照正則規(guī)則分割字符串车柠,返回一個(gè)由分割后的各個(gè)部分組成的數(shù)組。
- 該方法接受兩個(gè)參數(shù)塑猖,第一個(gè)參數(shù)是正則表達(dá)式竹祷,表示分隔規(guī)則,第二個(gè)參數(shù)是返回?cái)?shù)組的最大成員數(shù)羊苟。
// 非正則分隔
'a, b,c, d'.split(',')
// [ 'a', ' b', 'c', ' d' ]
// 正則分隔塑陵,去除多余的空格 --------------------------------- 重要
'a, b,c, d'.split(/, */)
// [ 'a', 'b', 'c', 'd' ]
// 指定返回?cái)?shù)組的最大成員
'a, b,c, d'.split(/, */, 2)
[ 'a', 'b' ]
匹配規(guī)則
字面量字符和元字符
- 如果在正則表達(dá)式之中,某個(gè)字符只表示它字面的含義践险,那么它們就叫做
“字面量字符”(literal characters)
- 除了字面量字符以外猿妈,還有一部分字符有特殊含義,不代表字面的意思巍虫。它們叫做
“元字符”(metacharacters)
(1)點(diǎn)字符(.)
- 點(diǎn)字符(.)匹配除
回車(\r)
彭则、換行(\n)
、行分隔符(\u2028)
和段分隔符(\u2029)
以外的所有字符占遥。
(2)位置字符(^ $)
- 位置字符用來(lái)提示字符所處的位置俯抖,主要有兩個(gè)字符。
- ^ 表示字符串的開(kāi)始位置
- $ 表示字符串的結(jié)束位置
(3)選擇符(|)
- 豎線符號(hào)(|)在正則表達(dá)式中表示“或關(guān)系”(OR)
- 即cat|dog表示匹配cat或dog瓦胎。
- 多個(gè)選擇符可以聯(lián)合使用
- 選擇符會(huì)包括它前后的多個(gè)字符芬萍,比如/ab|cd/指的是匹配ab或者cd尤揣,而不是指匹配b或者c。如果想修改這個(gè)行為柬祠,可以使用圓括號(hào)北戏。
// 匹配fred、barney漫蛔、betty之中的一個(gè)
/fred|barney|betty/
--------------
/a( |\t)b/.test('a\tb') -----------------true a和b之間有一個(gè)空格或者一個(gè)制表符嗜愈。
轉(zhuǎn)義符 ( \ )
- 正則表達(dá)式中那些有特殊含義的元字符,如果要匹配它們本身莽龟,就需要在它們前面要加上反斜杠蠕嫁,進(jìn)行轉(zhuǎn)義。
- 正則表達(dá)式中毯盈,需要反斜杠轉(zhuǎn)義的剃毒,一共有12個(gè)字符
-
^
、.
搂赋、[
赘阀、$
、(
厂镇、)
纤壁、|
左刽、*
捺信、+
、?
欠痴、{
和\\
正則表達(dá)式中迄靠,需要加反斜杠轉(zhuǎn)義的,一共有12個(gè)字符:
^ $ . | ( ) [ { 喇辽? * + \\
點(diǎn)字符( . )
位置字符( ^ $ )
選擇符( | )
量詞符( ? * + )
字符類( [ )
重復(fù)類( { )
組匹配( ( ) )
雙反斜杠 ( \\ )
- 需要特別注意的是掌挚,如果使用RegExp方法生成正則對(duì)象,轉(zhuǎn)義需要使用兩個(gè)斜杠菩咨,因?yàn)樽址畠?nèi)部會(huì)先轉(zhuǎn)義一次吠式。
(new RegExp('1\+1')).test('1+1')
// false
(new RegExp('1\\+1')).test('1+1')
// true
上面代碼中,RegExp作為構(gòu)造函數(shù)抽米,參數(shù)是一個(gè)字符串特占。
但是,在字符串內(nèi)部云茸,反斜杠也是轉(zhuǎn)義字符是目,
所以它會(huì)先被反斜杠轉(zhuǎn)義一次,然后再被正則表達(dá)式轉(zhuǎn)義一次标捺,因此需要兩個(gè)反斜杠轉(zhuǎn)義懊纳。
特殊字符
- 正則表達(dá)式對(duì)一些不能打印的特殊字符揉抵,提供了表達(dá)方法。
\cX 表示Ctrl-[X]嗤疯,其中的X是A-Z之中任一個(gè)英文字母冤今,用來(lái)匹配控制字符。
[\b] 匹配退格鍵(U+0008)茂缚,不要與\b混淆辟汰。
\n 匹配換行鍵。 -------------------------------- new line
\r 匹配回車鍵阱佛。 -------------------------------- return
\t 匹配制表符 tab(U+0009)帖汞。
\v 匹配垂直制表符(U+000B)。
\f 匹配換頁(yè)符(U+000C)凑术。
\0 匹配null字符(U+0000)翩蘸。
\xhh 匹配一個(gè)以兩位十六進(jìn)制數(shù)(\x00-\xFF)表示的字符。
\uhhhh 匹配一個(gè)以四位十六進(jìn)制數(shù)(\u0000-\uFFFF)表示的 Unicode 字符淮逊。
字符類 ( [ ] )
------ 表示一系列的字符可供選擇催首,只要匹配其中一個(gè)就可以。
- 字符類(class)表示有一系列字符可供選擇泄鹏,只要匹配其中一個(gè)就可以了郎任。
- 所有可供選擇的字符都放在方括號(hào)內(nèi),比如[xyz] 表示x备籽、y舶治、z之中任選一個(gè)匹配。
- 有兩個(gè)字符在字符類中有特殊含義车猬。
(1)脫字符(^)
- 如果方括號(hào)內(nèi)的第一個(gè)字符是[^]霉猛,則表示除了字符類之中的字符,其他字符都可以匹配珠闰。
- [^xyz]表示除了x惜浅、y、z之外都可以匹配伏嗜。
- 如果方括號(hào)內(nèi)沒(méi)有其他字符坛悉,即只有
[^],就表示匹配一切字符
承绸,其中包括換行符裸影。
相比之下,點(diǎn)號(hào)作為元字符(.)是不包括換行符的八酒。
- 注意空民,脫字符只有在字符類的第一個(gè)位置才有特殊含義,否則就是字面含義。
(2)連字符(-)
- 某些情況下界轩,對(duì)于連續(xù)序列的字符画饥,連字符(-)用來(lái)提供簡(jiǎn)寫形式,表示字符的連續(xù)范圍浊猾。
- 比如:
- [abc]可以寫成[a-c]
- [0123456789]可以寫成[0-9]
- 同理[A-Z]表示26個(gè)大寫字母
/a-z/.test('b') // false
/[a-z]/.test('b') // true
上面代碼中抖甘,當(dāng)連字號(hào)(dash)不出現(xiàn)在方括號(hào)之中,就不具備簡(jiǎn)寫的作用葫慎,只代表字面的含義衔彻,所以不匹配字符b。
只有當(dāng)連字號(hào)用在方括號(hào)之中偷办,才表示連續(xù)的字符序列艰额。
[0-9.,]
[0-9a-fA-F]
[a-zA-Z0-9-]
[1-31]
這些都是合法的字符類簡(jiǎn)寫形式
-----------------------------
[1-31] ----------------------------------- 不代表1到31,只代表1到3椒涯。
/([12][0-9])|(3[01])/ -------------------- 表示1到31
- 另外柄沮,不要過(guò)分使用連字符,設(shè)定一個(gè)很大的范圍废岂,否則很可能選中意料之外的字符祖搓。最典型的例子就是[A-z],表面上它是選中從大寫的A到小寫的z之間52個(gè)字母湖苞,但是由于在 ASCII 編碼之中拯欧,大寫字母與小寫字母之間還有其他字符,結(jié)果就會(huì)出現(xiàn)意料之外的結(jié)果财骨。
預(yù)定義模式
\d 匹配0-9之間的任一數(shù)字镐作,相當(dāng)于[0-9]。 --------------------- digit 數(shù)字
\D 匹配所有0-9以外的字符蚓再,相當(dāng)于[^0-9]滑肉。
\w 匹配任意的字母包各、數(shù)字和下劃線摘仅,相當(dāng)于[A-Za-z0-9_]。
\W 除所有字母问畅、數(shù)字和下劃線以外的字符娃属,相當(dāng)于[^A-Za-z0-9_]。
\s 匹配空格(包括換行符护姆、制表符矾端、空格符等),相等于[ \t\r\n\v\f]卵皂。
\S 匹配非空格的字符秩铆,相當(dāng)于[^ \t\r\n\v\f]。
\b 匹配詞的邊界。 --------------------- boundary 邊界
\B 匹配非詞邊界殴玛,即在詞的內(nèi)部捅膘。
- [\S\s]指代一切字符。
重復(fù)類
- 模式的精確匹配次數(shù)滚粟,使用大括號(hào)({})表示寻仗。
- {n}表示恰好重復(fù)n次,
- {n,}表示至少重復(fù)n次凡壤,
- {n,m}表示重復(fù)不少于n次署尤,不多于m次。
量詞符
? 問(wèn)號(hào)表示某個(gè)模式出現(xiàn)0次或1次亚侠,等同于{0, 1}曹体。
* 星號(hào)表示某個(gè)模式出現(xiàn)0次或多次,等同于{0,}硝烂。
+ 加號(hào)表示某個(gè)模式出現(xiàn)1次或多次混坞,等同于{1,}。
貪婪模式 ---------------- 3個(gè)量詞符是貪婪模式
三個(gè)量詞符钢坦,默認(rèn)情況下都是最大可能匹配究孕,即匹配直到下一個(gè)字符不滿足匹配規(guī)則為止。這被稱為貪婪模式爹凹。
- 如果想將貪婪模式改為非貪婪模式厨诸,可以在量詞符后面加一個(gè)問(wèn)號(hào)。!!!!!!!!!!!!!!!!
var a = 'aaaaa';
var b = a.match(/a+/);
console.log(b); ------------------------------- ["aaaaa", index: 0, input: "aaaaa"]
var c = a.match(/a*/);
console.log(c) ------------------------------- ["aaaaa", index: 0, input: "aaaaa"]
3個(gè)量詞符的匹配 默認(rèn)是貪婪模式
----------------------------
要將貪婪模式轉(zhuǎn)化為 非貪婪模式禾酱,就要在量詞符后面加一個(gè)問(wèn)號(hào)
----> 量詞符后面加問(wèn)號(hào) ----> 轉(zhuǎn)化成非貪婪模式
var a = 'aaaaa';
var b = a.match(/a+?/); ------------------------------ ["a", index: 0, input: "aaaaa"]
console.log(b);
var c = a.match(/a*?/); ------------------------------ ["", index: 0, input: "aaaaa"]
console.log(c)
- 除了非貪婪模式的加號(hào)微酬,還有非貪婪模式的星號(hào)(*)
*?:表示某個(gè)模式出現(xiàn)0次或多次,匹配時(shí)采用非貪婪模式颤陶。
+?:表示某個(gè)模式出現(xiàn)1次或多次颗管,匹配時(shí)采用非貪婪模式。
修飾符
修飾符(modifier)表示模式的附加規(guī)則滓走,放在正則模式的最尾部垦江。
- modifier:修飾符的意思
- 修飾符可以單個(gè)使用,也可以多個(gè)一起使用搅方。
(1)g 修飾符 ---------- global
- 默認(rèn)情況下比吭,第一次匹配成功后,正則對(duì)象就停止向下匹配了姨涡。g修飾符表示全局匹配(global)衩藤,加上它以后,正則對(duì)象將匹配全部符合條件的結(jié)果涛漂,
主要用于搜索和替換赏表。
var regex = /b/;
var str = 'abba';
regex.test(str); // true ------------------------------------- 不加g,正則每次都從頭開(kāi)始匹配
regex.test(str); // true
regex.test(str); // true
上面代碼中,正則模式不含g修飾符瓢剿,每次都是從字符串頭部開(kāi)始匹配岁诉。
所以,連續(xù)做了三次匹配跋选,都返回true涕癣。
-----------
var regex = /b/g;
var str = 'abba';
regex.test(str); // true
regex.test(str); // true
regex.test(str); // false
上面代碼中,正則模式含有g(shù)修飾符前标,每次都是從上一次匹配成功處坠韩,開(kāi)始向后匹配。
因?yàn)樽址產(chǎn)bba只有兩個(gè)b炼列,所以前兩次匹配結(jié)果為true只搁,第三次匹配結(jié)果為false。
(2)i 修飾符
- 默認(rèn)情況下俭尖,正則對(duì)象區(qū)分字母的大小寫氢惋,加上i修飾符以后表示忽略大小寫(ignorecase)
(3)m 修飾符 ---- multiline多行模式,匹配換行符 \n
- m修飾符表示多行模式(multiline)稽犁,會(huì)修改^和$的行為焰望。
- 默認(rèn)情況下(即不加m修飾符時(shí)),
^
和$
匹配字符串的開(kāi)始處和結(jié)尾處已亥, - 加上m修飾符以后熊赖,
^
和$
還會(huì)匹配行首和行尾,即^和$會(huì)識(shí)別換行符(\n)虑椎。
/world$/.test('hello world\n') // false
/world$/m.test('hello world\n') // true
/^b/m.test('a\nb') // true
------------------ a\nb 換行了震鹉,加了m,b就是在行首
上面代碼要求匹配行首的b捆姜,如果不加m修飾符传趾,就相當(dāng)于b只能處在字符串的開(kāi)始處。
加上b修飾符以后泥技,換行符\n也會(huì)被認(rèn)為是一行的開(kāi)始浆兰。
組匹配
- 正則表達(dá)式的括號(hào)表示分組匹配,括號(hào)中的模式可以用來(lái)匹配分組的內(nèi)容零抬。
/fred+/.test('fredd') // true
/(fred)+/.test('fredfred') // true
- 注意镊讼,使用組匹配時(shí),不宜同時(shí)使用g修飾符,否則match方法不會(huì)捕獲分組的內(nèi)容。
var m = 'abcabc'.match(/(.)b(.)/g);
m // ['abc', 'abc']
組匹配時(shí)板甘,不宜使用g修飾符熄赡,上面情況就匹配了整個(gè)正則,而沒(méi)有匹配組