網(wǎng)站首頁 編程語言 正文
一、原型和原型鏈條
1.原型
<script>
/*
原型
+ 解決問題
=> 當你需要給實例對象添加方法
=> 直接書寫在構造函數(shù)體內
=> 這個行為并不好
=> 我們的原型就是解決了這個問題
+ 不好的原因
=> 當我把方法書寫在構造函數(shù)體內
=> 每次創(chuàng)建實例的時候, 都會創(chuàng)建一個函數(shù)數(shù)據(jù)類型
=> 多個函數(shù)方法, 一模一樣, 但是占據(jù)了多分存儲空間
*/
function Person(name, age) {
// 向實例對象內添加屬性
this.name = name
this.age = age
// 向實例對象內添加方法
// 在構造函數(shù)體內直接向實例對象添加方法, 這個行為并不好
this.sayHi = function () { console.log('hello world') }
}
// 創(chuàng)建一個實例
var p1 = new Person('Jack', 18)
// 創(chuàng)建第二個實例
var p2 = new Person('Rose', 20)
console.log(p1)
console.log(p2)
console.log(p1.sayHi)
console.log(p2.sayHi)
console.log(p2.sayHi === p1.sayHi)
</script>
2.解決問題
<script>
解決問題
+ 原型
=> 概念: 每一個構造函數(shù)天生自帶一個 prototype 屬性, 是一個對象數(shù)據(jù)類型
=> 概念: 每一個對象天生自帶一個屬性 __proto__, 指向所屬構造函數(shù)的 prototype
=> 概念: 當你訪問對象的成員的時候, 首先在自己身上查找, 如果沒有, 自動去到 __proto__ 上查找
+ 如何解決問題
=> 我們把需要添加給實例的方法, 放在構造函數(shù)的原型(prototype)上
=> 就可以有實例進行訪問使用
+ 原型:
=> 構造函數(shù)天生自帶的一個 prototype
=> 作用: 有構造函數(shù)添加方法, 專門給實例對象使用
// 當函數(shù)被書寫完畢以后
// 就會有 prototype 出現(xiàn)
// function Person() {}
// // 直接向 prototype 內添加一些成員
// Person.prototype.a = 100
// Person.prototype.b = 200
// console.log(Person.prototype)
// // 創(chuàng)建一個實例對象
// // p1 所屬的構造函數(shù)就是 Person
// // p1.__proto__ === Person.prototype
// var p1 = new Person()
// console.log(p1.__proto__ === Person.prototype)
// console.log(p1.__proto__)
// // 當你訪問 p1 的 a 成員
// // 因為當你訪問 p1.a 的時候, 自己沒有, 會自動去自己的 __proto__ 上查找
// // 又因為 自己的__proto__ 就是 Perosn.prototype
// // 所以, 其實就是去到 Person.prototype 上查找
// console.log(p1.a)
function Person(name, age) {
// 向實例對象上添加屬性
this.name = name
this.age = age
// 向實例對象上添加方法
// this.sayHi = function () { console.log('hello world') }
}
// 把想添加給實例對象的方法, 書寫原型上
Person.prototype.sayHi = function () { console.log('hello world') }
// 創(chuàng)建實例對象
// p1 和 p2 所屬的構造函數(shù)都是 Person
// p1.__proto__ === Person.prototype
// p2.__proto__ === Person.prototype
var p1 = new Person('Jack', 18)
var p2 = new Person('Rose', 20)
console.log(p1)
console.log(p2)
console.log(p1.__proto__ === Person.prototype)
console.log(p2.__proto__ === Person.prototype)
// 當你訪問 p1 的sayHi 的時候
// 自己沒有, 回去自己的 __proto__ 上找
console.log(p1.sayHi)
// 當你訪問 p2 的sayHi 的會搜
// 自己沒有, 會去自己的 __proto__ 上找
console.log(p2.sayHi)
// 因為 p1.__proto__ 和 p2.__proto__ 是一個對象空間
// p1 和 p2 的 sayHi 是一個
console.log(p1.sayHi === p2.sayHi)
</script>
3.原型鏈
<script>
問題1: 實例對象身上的 __proto__ 指向誰 ?
=> 指向所屬構造函數(shù)的 prototype
=> p1 所屬的構造函數(shù)是 Person
=> p1.__proto__ 指向 Person.prototype
問題2: Person.prototype 的 __proto__ 指向誰 ?
=> Person.prototype 所屬的構造函數(shù)是誰
=> 因為 Perosn.prototype 是一個對象數(shù)據(jù)類型(Object)
=> 在 JS 內所有的 Object 數(shù)據(jù)類型都是屬于 Object 這個內置構造函數(shù)
=> Person.prototype 是屬于 Object 這個內置構造函數(shù)的
=> Person.prototype 的 __proto__ 指向 Object.prototype
問題3: Person 的 __proto__ 指向誰 ?
=> Person 是一個函數(shù), 函數(shù)本身也是一個對象, 就會有 __proto__
=> 在 JS 內, 所有的函數(shù)都是屬于內置構造函數(shù) Function 的實例
=> Person.__proto__ 指向 Function.prototype
問題4: Object.prototype 的 __proto__ 指向誰 ?
=> Object.prototype 是一個對象數(shù)據(jù)類型, 只要是對象, 都是數(shù)據(jù) Object 這個內置構造函數(shù)的
=> 注意: Object.prototype 在 JS 內叫做頂級原型, 不在有 __proto__ 了
=> Object.prototype 的 __proto__ 指向 null
問題5: Object 的 __proto__ 指向誰 ?
=> Object 是內一個內置構造函數(shù), 同時也是一個函數(shù), 同時也是一個對象
=> 在 JS 內, 所以的函數(shù)都是屬于內置構造函數(shù) Function 的實例
=> Object 也是 Function 的實例
=> Object.__proto__ 指向 Function.prototype
問題6: Function.prototype 的 __proto__ 指向誰 ?
=> Function.prototype 也是一個對象數(shù)據(jù)類型
=> 只要是對象數(shù)據(jù)類型都是 Object 的實例
=> Function.prototype 的 __proto__ 指向 Object.prototype
問題7: Function 的 __proto__ 指向誰 ?
=> Function 也是一個內置構造函數(shù), 也是一個函數(shù)
=> 在 JS 內, 所有的函數(shù)都是屬于內置構造函數(shù) Function 的實例
=> Function 自己是自己的構造函數(shù)
=> Function 自己是自己的實例對象
=> Function 所屬的構造函數(shù)的是 Function
原型鏈
+ 用 __proto__ 串聯(lián)起來的對象鏈狀結構
+ 注意: 使用 __proto__
+ 每一個對象數(shù)據(jù)類型, 都有一個屬于自己的原型鏈
+ 作用: 為了訪問對象成員
對象訪問機制:
+ 當你需要訪問對象的成員的時候
+ 首先在自己身上查找, 如果有直接使用
+ 如果沒有, 會自動去 __proto__ 上查找
+ 如果還沒有, 就再去 __proto__ 上查找
+ 直到 Object.prototype 都沒有, 那么返回 undefined
function Person() {}
var p1 = new Person()
</script>
二、ES6
1.ES6定義變量
<script>
// 1. 預解析
// console.log(num)
// var num = 100
// console.log(num)
// 定義之前使用 let 聲明的變量會報錯
// console.log(num2)
// let num2 = 200
// console.log(num2)
// 定義之前使用 const 聲明的變量會報錯
// console.log(num3)
// const num3 = 300
// console.log(num3)
// 2. 重復變量名
// var n1 = 100
// var n1 = 200
// console.log(n1)
// let n2 = 100
// let n2 = 200
// const n3 = 100
// const n3 = 200
// 3. 塊級作用域
// 任何一個可以執(zhí)行代碼段的 {} 都會限制該變量的使用范圍
// if (true) {
// var num = 100
// console.log(num)
// }
// console.log(num)
// if (true) {
// // 因為這個 num 使用 let 關鍵字定義的
// // 所以只能在這個 if 的 {} 內使用
// let num = 100
// console.log(num)
// }
// console.log(num)
// if (true) {
// // 因為這個 num 使用 const 關鍵字定義的
// // 所以只能在這個 if 的 {} 內使用
// const num = 100
// console.log(num)
// }
// console.log(num)
// 4. 定義時不賦值
// let num
// console.log(num)
// num = 100
// console.log(num)
// 使用 const 的時候, 聲明時必須賦值
// const num
// console.log(num)
// num = 100
// console.log(num)
// 5. 修改
// let num = 100
// console.log(num)
// num = 200
// console.log(num)
const num = 100
console.log(num)
// 你試圖修改 num 的值, 但是因為是 const 定義的, 不能修改
num = 200
console.log(num)
</script>
2.ES6的箭頭函數(shù)
<script>
// var fn1 = function () { console.log('我是 fn1 函數(shù)') }
// fn1()
// var fn2 = () => { console.log('我是 fn2 函數(shù)') }
// fn2()
/*
箭頭函數(shù)的特殊之處
1. 箭頭函數(shù)某些時候可以省略 ()
=> 當你的形參只有一個的時候, 可以不寫 ()
2. 箭頭函數(shù)某些時候可以省略 {}
=> 當你的代碼只有一句話的時候, 可以不寫 {}
=> 并且會自動把這一句話的結果當做函數(shù)的返回值
3. 箭頭函數(shù)內沒有 arguments
4. 箭頭函數(shù)內沒有 this
=> 箭頭函數(shù)內的 this 就是外部作用域的 this
*/
// 1.
// var fn1 = () => { console.log('我沒有形參') }
// fn1()
// var fn2 = a => { console.log('我一個形參 : ', a) }
// fn2(100)
// var fn3 = (a, b) => { console.log('我兩個形參: ', a, b) }
// fn3(100, 200)
// 2.
// var fn1 = (a, b) => a + b
// console.log(fn1(10, 20))
// 3.
// var fn1 = () => {
// console.log(arguments)
// }
// fn1(100, 200, 300)
// var fn2 = function () {
// console.log(arguments)
// }
// fn2(100, 200, 300)
// 4.
var obj = {
fn: function () { console.log(this) },
fn2: () => { console.log(this) }
}
obj.fn() // this 因為 fn 函數(shù)被 obj 調用, 所以 this 是 obj
obj.fn2() // 因為是箭頭函數(shù), 內部沒有 this, 就是外部作用域的 this
</script>
3.ES6的函數(shù)默認值
<script>
function fn(a = 100, b = 200) {
// 表示聲明了兩個形參
// 其中 a 設置默認值為 100
// 其中 b 設置默認值為 200
console.log('a : ', a)
console.log('b : ', b)
console.log('---------------------')
}
// 兩個實參都沒有傳遞, 都會使用默認值
fn()
// 給 a 進行了賦值, a 就使用 10
// b 繼續(xù)使用默認值 200
fn(10)
// 給 a 進行了賦值, a 就使用 10
// 給 b 進行了賦值, b 就使用 20
fn(10, 20)
</script>
4.ES6 解構賦值
<script>
// 1. 解構數(shù)組
// var arr = [ 'hello', 'world' ]
// // 開始解構
// // 注意: 解構數(shù)組使用 []
// // a 獲取的內容就是 arr[0]
// // b 獲取的內容就是 arr[1]
// var [ a, b ] = arr
// console.log(a)
// console.log(b)
// 2. 解構對象
var obj = { name: 'Jack', age: 18 }
// 開始解構
// 注意: 解構對象使用 {}
// 表示定義一個叫做 name 的變量, 獲取的是 obj 內一個叫做 name 的成員的值
// var { name, age, a } = obj
// console.log(name)
// console.log(age)
// console.log(a)
// var a = obj.age
// console.log(a)
// 相當于定義變量 a 從 obj 內獲取一個叫做 a 的成員的值
// var { a } = obj
// console.log(a)
// 可以起一個別名
// 相當于頂一個 a 變量, 從 obj 內獲取一個叫做 age 的值
var { age: a } = obj // => var a = obj.age
console.log(a)
</script>
5.ES6的模板字符串
<script>
+ 其實, 就是 ES6 內新增的定義字符串的方式
+ 以前:
=> var str = '內容'
=> var str = "內容"
+ 現(xiàn)在:
=> var str = `內容`
區(qū)別:
1. 可以換行書寫
2. 可以直接在字符串內解析變量
=> 當你需要解析變量的時候, 直接書寫 ${ 變量 }
// 1.
// var s1 = 'hello world'
// var s2 = "hello world"
// var s3 = `
// hello
// world
// `
// console.log(s1)
// console.log(s2)
// console.log(s3)
// 2.
var age = 18
var s1 = `我叫前端小灰狼, 今年 ${age} 歲`
console.log(s1)
var s2 = '我叫前端小灰狼, 今年 ${age} 歲'
console.log(s2)
var s3 = "我叫前端小灰狼, 今年 ${age} 歲"
console.log(s3)
</script>
6.ES6 的展開運算符
<script>
/*
+ ...
+ 作用: 展開數(shù)組的[] 或者展開對象的 {}
*/
// console.log(100, 200, 300, 400)
// var arr = [ 100, 200, 300, 400 ]
// console.log(arr)
// console.log(...arr)
// 作用1: 合并數(shù)組
// var arr1 = [ 10, 20 ]
// var arr2 = [ 30, 40 ]
// var arr3 = [ 50, 60, 70 ]
// var arr4 = [ 80, 90 ]
// var arr5 = [ ...arr1, ...arr2, ...arr3, ...arr4 ]
// console.log(arr5)
// 作用2: 給函數(shù)傳遞參數(shù)
// var arr1 = [ 10, 20, 17, 7, 31, 22, 12 ]
// // var max = Math.max(10, 20, 17, 7, 31, 22, 12)
// // var max = Math.max(arr1)
// var max = Math.max(...arr1)
// console.log(max)
// 展開對象
var obj = { name: 'Jack', age: 18 }
console.log(obj)
// 作用1: 用來復制對象
// 注意: 展開書寫的順序問題, 在有相同成員的時候
var obj2 = {
gender: '男',
...obj,
name: 'Rose',
}
console.log(obj2)
</script>
7.ES6 的類語法
<script>
/*
ES6 的類語法
+ 語法:
class 類名 {
// 原先 ES5 內的構造函數(shù)體
constructor () {}
// 直接書寫原型上的方法即可
// 書寫靜態(tài)屬性和方法, 需要加上一個 static 關鍵字即可
}
+ 注意: 必須和 new 關鍵字連用
=> 不和 new 關鍵字連用, 會直接報錯
*/
// function Person(name, age) {
// this.name = name
// this.age = age
// }
// // 原型添加一個方法
// // 2. 原型上的方法, 目的是為了給 實例使用
// Person.prototype.sayHi = function () { console.log('hello world') }
// // 書寫靜態(tài)屬性和方法
// Person.a = 100
// Person.go = function () { console.log('跑起來') }
// var p1 = new Person('jack', 18)
// console.log(p1)
// p1.sayHi()
// // 1. 構造函數(shù)本質還是一個函數(shù), 可以不和 new 關鍵字連用
// var p2 = Person('Rose', 20)
// console.log(p2)
// console.log(Person.a)
// Person.go()
// 類的書寫
class Person {
constructor (name, age) {
// 這里按照 ES5 的構造函數(shù)體書寫
this.name = name
this.age = age
}
// 直接書寫原型上的方法即可
sayHi () { console.log('你好 世界') }
// 靜態(tài)屬性
static a = 100
// 靜態(tài)方法
static go () { console.log('running') }
}
var p1 = new Person('張三', 18)
console.log(p1)
p1.sayHi()
// 使用靜態(tài)屬性和靜態(tài)方法
Person.go()
console.log(Person.a)
</script>
三、前后端交互Ajax
1.第一次嘗試 ajax
<script>
// 1. 創(chuàng)建一個 ajax 對象
var xhr = new XMLHttpRequest()
// 2. 配置本次的請求信息
// 請求方式: 按照接口文檔來進行書寫
// 請求地址: 按照接口文檔來進行書寫
// 是否異步: 默認是 true 表示異步請求, 選填為 false, 表示同步請求
xhr.open('GET', 'http://localhost:8888/test/first', true)
// 3. 配置一個請求完成后觸發(fā)的事件
// 請求完整: 本次請求發(fā)送出去, 服務器接收到了我們的請求, 并且服務器返回的信息已經(jīng)回到了瀏覽器
xhr.onload = function () {
// 如何拿到后端返回的信息
// 語法: xhr.responseText
console.log(xhr.responseText)
}
// 4. 把本次請求發(fā)送出去
xhr.send()
</script>
2.第二次測試 ajax
<script>
// 1. 創(chuàng)建ajax 對象
var xhr = new XMLHttpRequest()
// 2. 配置本次的請求信息
xhr.open('GET', 'http://localhost:8888/test/second', true)
// 3. 配置請求完成的事件
xhr.onload = function () {
// 當后端返回的是 json 格式字符串的時候, 我們需要進行單獨的解析
// 語法: JSON.parse(json格式字符串)
// 返回值: 解析好的 js 格式的數(shù)據(jù)
var res = JSON.parse(xhr.responseText)
console.log(res)
}
// 4. 發(fā)送出去
xhr.send()
</script>
3.GET 和 POST 請求
<script>
// 1. GET 請求
// var xhr = new XMLHttpRequest()
// // 需要攜帶參數(shù)
// // 因為是 GET 請求, 直接在地址后面進行參數(shù)的書寫
// xhr.open('GET', 'http://localhost:8888/test/third?name=前端小灰狼&age=18', true)
// xhr.onload = function () {
// console.log(JSON.parse(xhr.responseText))
// }
// xhr.send()
// 2. POST 請求
var xhr = new XMLHttpRequest()
// 注意: 因為是 POST 請求, 不需要在地址后面拼接參數(shù)
xhr.open('POST', 'http://localhost:8888/test/fourth', true)
xhr.onload = function () {
console.log(JSON.parse(xhr.responseText))
}
// 注意: 當你發(fā)送 POST 請求, 并且需要攜帶參數(shù)的時候, 需要進行特殊說明
// 語法: xhr.setRequestHeader('content-type', 你傳遞參數(shù)的格式)
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
// send 后面的() 就是書寫請求體的位置
xhr.send('name=前端小灰狼&age=18')
</script>
4.登錄案例
<!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>
* {
margin: 0;
padding: 0;
}
form {
width: 500px;
padding: 20px;
margin: 50px auto;
border: 3px solid pink;
display: flex;
flex-direction: column;
font-size: 30px;
padding-top: 50px;
position: relative;
}
form > span {
position: absolute;
left: 50%;
top: 5px;
transform: translateX(-50%);
width: 100%;
text-align: center;
color: red;
display: none;
}
form > label {
height: 50px;
}
form > label > input {
font-size: 24px;
height: 40px;
padding-left: 20px;
}
</style>
</head>
<body>
<form>
<span class="error">用戶名或者密碼錯誤!!</span>
<label>
用戶名 : <input class="username" type="text">
</label>
<label>
密 碼 : <input class="password" type="text">
</label>
<button>登錄</button>
</form>
<script>
/*
案例 - 登錄
分析需求:
+ 問題1: 什么時候進行發(fā)送請求 ?
=> 點擊登錄按鈕的時候
=> 需要給 form 標簽綁定一個表單提交事件
+ 問題2: 需要拿到哪些信息 ?
=> 需要拿到用戶填寫的用戶名和密碼
+ 問題3: 需要如何發(fā)送給后端 ?
=> 按照接口文檔的規(guī)范進行發(fā)送
+ 問題4: 請求完成以后, 我們需要做什么 ?
=> 根據(jù)后端返回的信息, 進行一些后續(xù)的操作
=> 如果后端返回的信息是登錄成功, 那么我們進行頁面跳轉
=> 如果后端返回的是登錄失敗, 那么我們提示用戶錯誤
*/
// 0. 獲取元素
// 0-1. form 標簽
var loginForm = document.querySelector('form')
// 0-2. 用戶名文本框
var nameInp = document.querySelector('.username')
// 0-3. 密碼文本框
var pwdInp = document.querySelector('.password')
// 0-4. 錯誤提示文本
var errBox = document.querySelector('.error')
// 1. 給 form 標簽綁定一個表單提交事件
loginForm.onsubmit = function (e) {
// 注意: 阻止表單的默認提交行為
e.preventDefault()
// 2. 拿到填寫的用戶名和密碼
var name = nameInp.value
var pwd = pwdInp.value
// 2-2. 驗證用戶名和密碼
if (!name || !pwd) return alert('請完整填寫表單')
// 3. 發(fā)送 ajax 請求
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://localhost:8888/users/login', true)
xhr.onload = function () {
// 因為后端返回的是 json 格式數(shù)據(jù)
var res = JSON.parse(xhr.responseText)
console.log(res)
// 進行條件判斷
if (res.code === 0) {
// 登錄失敗了
errBox.style.display = 'block'
} else {
// 登錄成功了
window.location.href = './home.html'
}
}
// 注意: POST 請求攜帶參數(shù)需要提前說明
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
// 因為 POST 請求攜帶參數(shù)是在請求體內
xhr.send('username=' + name + '&password=' + pwd)
}
</script>
</body>
</html>
原文鏈接:https://blog.csdn.net/weixin_44145338/article/details/131859690
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-07-01 python神經(jīng)網(wǎng)絡Pytorch中Tensorboard函數(shù)使用_python
- 2022-11-18 Android?使用壓縮紋理的方案_Android
- 2022-04-30 C#繪制實時曲線圖的方法詳解_C#教程
- 2023-02-17 Python排序算法之冒泡排序_python
- 2022-02-02 appname is automatically signed for development,
- 2023-01-12 C語言技巧提升之回調函數(shù)的掌握_C 語言
- 2022-04-11 SQL?Server的觸發(fā)器你了解多少_MsSql
- 2023-03-29 Python之sklearn數(shù)據(jù)預處理中fit(),transform()與fit_transfor
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支