-
當前位置:首頁 > 創(chuàng)意學院 > 營銷推廣 > 專題列表 > 正文
js底層代碼(javascript底層代碼)
大家好!今天讓創(chuàng)意嶺的小編來大家介紹下關于js底層代碼的問題,以下是小編對此問題的歸納整理,讓我們一起來看看吧。
開始之前先推薦一個非常厲害的Ai人工智能工具,一鍵生成原創(chuàng)文章、方案、文案、工作計劃、工作報告、論文、代碼、作文、做題和對話答疑等等
只需要輸入關鍵詞,就能返回你想要的內(nèi)容,有小程序、在線網(wǎng)頁版、PC客戶端和批量生成器
問友Ai官網(wǎng):https://ai.de1919.com。
本文目錄:
JS怎么點擊底層的圖片
你對標注的圖片綁定滾輪事件,在事件代碼里,用js代碼模擬觸發(fā)底層圖片的滾輪事件就可以了vue實現(xiàn)路由跳轉(zhuǎn)的原理是什么,是調(diào)用js底層什么方法
前端路由是直接找到與地址匹配的一個組件或?qū)ο蟛⑵滗秩境鰜怼8淖優(yōu)g覽器地址而不向服務器發(fā)出請求有兩種方式:1. 在地址中加入#以欺騙瀏覽器,地址的改變是由于正在進行頁內(nèi)導航
2. 使用H5的window.history功能,使用URL的Hash來模擬一個完整的URL。
當打包構建應用時,Javascript 包會變得非常大,影響頁面加載。如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就更加高效了。
目錄結構
先來看看整體的目錄結構
和流程相關的主要需要關注點的就是 components、history 目錄以及 create-matcher.js、create-route-map.js、index.js、install.js。下面就從 basic 應用入口開始來分析 vue-router 的整個流程。
import Vue from 'vue'
import VueRouter from 'vue-router'
// 1. 插件
// 安裝 <router-view> and <router-link> 組件
// 且給當前應用下所有的組件都注入 $router and $route 對象
Vue.use(VueRouter)
// 2. 定義各個路由下使用的組件,簡稱路由組件
const Home = { template: '<div>home</div>' }
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 3. 創(chuàng)建 VueRouter 實例 router
const router = new VueRouter({
mode: 'history',
base: __dirname,
routes: [
{ path: '/', component: Home },
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
})
// 4. 創(chuàng)建 啟動應用
// 一定要確認注入了 router
// 在 <router-view> 中將會渲染路由組件
new Vue({
router,
template: ` <div id="app">
<h1>Basic</h1>
<ul>
<li><router-link to="/">/</router-link></li>
<li><router-link to="/foo">/foo</router-link></li>
<li><router-link to="/bar">/bar</router-link></li>
<router-link tag="li" to="/bar">/bar</router-link>
</ul>
<router-view class="view"></router-view>
</div>
`
}).$mount('#app')123456789101112131415161718192021222324252627282930313233343536373839404142
作為插件
上邊代碼中關鍵的第 1 步,利用 Vue.js 提供的插件機制 .use(plugin) 來安裝 VueRouter,而這個插件機制則會調(diào)用該 plugin 對象的 install 方法(當然如果該 plugin 沒有該方法的話會把 plugin 自身作為函數(shù)來調(diào)用);下邊來看下 vue-router 這個插件具體的實現(xiàn)部分。
VueRouter 對象是在 src/index.js 中暴露出來的,這個對象有一個靜態(tài)的 install 方法:
/* @flow */
// 導入 install 模塊
import { install } from './install'// ...import { inBrowser, supportsHistory } from './util/dom'// ...export default class VueRouter {
// ...}
// 賦值 install
VueRouter.install = install
// 自動使用插件if (inBrowser && window.Vue) {
window.Vue.use(VueRouter)
}123456789101112131415161718
可以看到這是一個 Vue.js 插件的經(jīng)典寫法,給插件對象增加 install 方法用來安裝插件具體邏輯,同時在最后判斷下如果是在瀏覽器環(huán)境且存在 window.Vue 的話就會自動使用插件。
install 在這里是一個單獨的模塊,繼續(xù)來看同級下的 src/install.js 的主要邏輯:
// router-view router-link 組件import View from './components/view'import Link from './components/link'// export 一個 Vue 引用export let _Vue// 安裝函數(shù)export function install (Vue) {
if (install.installed) return
install.installed = true
// 賦值私有 Vue 引用
_Vue = Vue // 注入 $router $route
Object.defineProperty(Vue.prototype, '$router', {
get () { return this.$root._router }
}) Object.defineProperty(Vue.prototype, '$route', {
get () { return this.$root._route }
}) // beforeCreate mixin
Vue.mixin({
beforeCreate () { // 判斷是否有 router
if (this.$options.router) { // 賦值 _router
this._router = this.$options.router // 初始化 init
this._router.init(this) // 定義響應式的 _route 對象
Vue.util.defineReactive(this, '_route', this._router.history.current)
}
}
}) // 注冊組件
Vue.component('router-view', View)
Vue.component('router-link', Link)// ...}12345678910111213141516171819202122232425262728293031323334353637383940414243
這里就會有一些疑問了?
· 為啥要 export 一個 Vue 引用?
插件在打包的時候是肯定不希望把 vue 作為一個依賴包打進去的,但是呢又希望使用 Vue 對象本身的一些方法,此時就可以采用上邊類似的做法,在 install 的時候把這個變量賦值 Vue ,這樣就可以在其他地方使用 Vue 的一些方法而不必引入 vue 依賴包(前提是保證 install 后才會使用)。
· 通過給 Vue.prototype 定義 $router、$route 屬性就可以把他們注入到所有組件中嗎?
在 Vue.js 中所有的組件都是被擴展的 Vue 實例,也就意味著所有的組件都可以訪問到這個實例原型上定義的屬性。
beforeCreate mixin 這個在后邊創(chuàng)建 Vue 實例的時候再細說。
實例化 VueRouter
在入口文件中,首先要實例化一個 VueRouter ,然后將其傳入 Vue 實例的 options 中?,F(xiàn)在繼續(xù)來看在 src/index.js 中暴露出來的 VueRouter 類:
// ...import { createMatcher } from './create-matcher'// ...export default class VueRouter {
// ...
constructor (options: RouterOptions = {}) {
this.app = null
this.options = options
this.beforeHooks = []
this.afterHooks = []
// 創(chuàng)建 match 匹配函數(shù)
this.match = createMatcher(options.routes || [])
// 根據(jù) mode 實例化具體的 History
let mode = options.mode || 'hash'
this.fallback = mode === 'history' && !supportsHistory if (this.fallback) {
mode = 'hash'
} if (!inBrowser) {
mode = 'abstract'
}
this.mode = mode switch (mode) {
case 'history':
this.history = new HTML5History(this, options.base) break
case 'hash':
this.history = new HashHistory(this, options.base, this.fallback) break
case 'abstract':
this.history = new AbstractHistory(this) break
default:
assert(false, `invalid mode: ${mode}`)
}
}
// ...}123456789101112131415161718192021222324252627282930313233343536373839
里邊包含了重要的一步:創(chuàng)建 match 匹配函數(shù)。
match 匹配函數(shù)
匹配函數(shù)是由 src/create-matcher.js 中的 createMatcher 創(chuàng)建的:
/* @flow */
import Regexp from 'path-to-regexp'// ...import { createRouteMap } from './create-route-map'// ...export function createMatcher (routes: Array<RouteConfig>): Matcher {
// 創(chuàng)建路由 map
const { pathMap, nameMap } = createRouteMap(routes)
// 匹配函數(shù) function match (
raw: RawLocation,
currentRoute?: Route,
redirectedFrom?: Location
): Route {
// ...
} function redirect (
record: RouteRecord,
location: Location
): Route {
// ...
} function alias (
record: RouteRecord,
location: Location,
matchAs: string
): Route {
// ...
} function _createRoute (
record: ?RouteRecord,
location: Location,
redirectedFrom?: Location
): Route { if (record && record.redirect) { return redirect(record, redirectedFrom || location)
} if (record && record.matchAs) { return alias(record, location, record.matchAs)
} return createRoute(record, location, redirectedFrom)
}
// 返回 return match
}
// ...123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
具體邏輯后續(xù)再具體分析,現(xiàn)在只需要理解為根據(jù)傳入的 routes 配置生成對應的路由 map,然后直接返回了 match 匹配函數(shù)。
繼續(xù)來看 src/create-route-map.js 中的 createRouteMap 函數(shù):
/* @flow */import { assert, warn } from './util/warn'import { cleanPath } from './util/path'// 創(chuàng)建路由 mapexport function createRouteMap (routes: Array<RouteConfig>): {
pathMap: Dictionary<RouteRecord>,
nameMap: Dictionary<RouteRecord>
} { // path 路由 map
const pathMap: Dictionary<RouteRecord> = Object.create(null) // name 路由 map
const nameMap: Dictionary<RouteRecord> = Object.create(null) // 遍歷路由配置對象 增加 路由記錄
routes.forEach(route => {
addRouteRecord(pathMap, nameMap, route)
}) return {
pathMap,
nameMap
}
}// 增加 路由記錄 函數(shù)function addRouteRecord (
pathMap: Dictionary<RouteRecord>,
nameMap: Dictionary<RouteRecord>,
route: RouteConfig,
parent?: RouteRecord,
matchAs?: string
) {
// 獲取 path 、name
const { path, name } = route
assert(path != null, `"path" is required in a route configuration.`) // 路由記錄 對象
const record: RouteRecord = {
path: normalizePath(path, parent),
components: route.components || { default: route.component },
instances: {},
name, parent,
matchAs,
redirect: route.redirect,
beforeEnter: route.beforeEnter,
meta: route.meta || {}
} // 嵌套子路由 則遞歸增加 記錄
if (route.children) {// ...
route.children.forEach(child => {
addRouteRecord(pathMap, nameMap, child, record)
})
} // 處理別名 alias 邏輯 增加對應的 記錄
if (route.alias !== undefined) { if (Array.isArray(route.alias)) {
route.alias.forEach(alias => {
addRouteRecord(pathMap, nameMap, { path: alias }, parent, record.path)
})
} else {
addRouteRecord(pathMap, nameMap, { path: route.alias }, parent, record.path)
}
} // 更新 path map
pathMap[record.path] = record // 更新 name map
if (name) { if (!nameMap[name]) {
nameMap[name] = record
} else {
warn(false, `Duplicate named routes definition: { name: "${name}", path: "${record.path}" }`)
}
}
}function normalizePath (path: string, parent?: RouteRecord): string {
path = path.replace(/\/$/, '') if (path[0] === '/') return path if (parent == null) return path return cleanPath(`${parent.path}/${path}`)
}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
可以看出主要做的事情就是根據(jù)用戶路由配置對象生成普通的根據(jù) path 來對應的路由記錄以及根據(jù) name 來對應的路由記錄的 map,方便后續(xù)匹配對應。
實例化 History
這也是很重要的一步,所有的 History 類都是在 src/history/ 目錄下,現(xiàn)在呢不需要關心具體的每種 History 的具體實現(xiàn)上差異,只需要知道他們都是繼承自 src/history/base.js 中的 History 類的:
/* @flow */// ...import { inBrowser } from '../util/dom'import { runQueue } from '../util/async'import { START, isSameRoute } from '../util/route'// 這里從之前分析過的 install.js 中 export _Vueimport { _Vue } from '../install'export class History {// ...
constructor (router: VueRouter, base: ?string) { this.router = router this.base = normalizeBase(base) // start with a route object that stands for "nowhere"
this.current = START this.pending = null
}// ...}// 得到 base 值function normalizeBase (base: ?string): string { if (!base) { if (inBrowser) { // respect <base> tag
const baseEl = document.querySelector('base') base = baseEl ? baseEl.getAttribute('href') : '/'
} else { base = '/'
}
} // make sure there's the starting slash
if (base.charAt(0) !== '/') { base = '/' + base
javascript、Java、C++、C的底層編程語言分別是什么?
javascript是腳本語言,在客戶端運行,有個解釋器,wscript,應該是microsoft vc++寫的.至于VC版本是多少應該是看你的計算機系統(tǒng).java底層是C語言C的底層是匯編語言.其實都是由匯編語言寫的底層,然后逐層往上面翻譯。
《c++程序設計語言》 一本黑皮書上,第一章,1.3 程序節(jié) 里面的一些說法:
(應該是這本書:計算機科學叢書·C++程序設計)
COBOL(COmmon Business Oriented Language,通用商業(yè)程序設計語言)主要用于商業(yè)數(shù)據(jù)處理
FORTRAN(FORmula Translation,公式翻譯)主要用于數(shù)值計算。
BASIC(Beginner All-purpose Symbolic Instructional Code,初學者通用符號指令碼)易于學習和使用
Pascal(以Blaise Pascal命名)
Ada(以Ada lovelace 命名)是美國國防部開發(fā)的,主要用于國防項目。
Visual Basic(微軟開發(fā)的一種類Basic的可視化編程語言)圖形用戶界面的開發(fā)以及應用程序快速開發(fā)
Delphi (Borland公司開發(fā)的一種類Pascal 的可視化編程語言)圖形用戶界面的開發(fā)以及應用程序的快速開發(fā)
C(它的開發(fā)者先設計了B語言)結合了匯編語言的強大亨利和高級語言易于使用、移植性好的優(yōu)點。
C++(一種基于C的面向?qū)ο缶幊陶Z言)在系統(tǒng)軟件(如編譯器和操作系統(tǒng))開發(fā)領域得到了廣泛應用,windows操作系統(tǒng)就是用C++開發(fā)的
Java 是由sun公司開發(fā)的,廣泛用于Internet應用程序的開發(fā)。
C#(微軟開發(fā)的一種類Java的編程語言)。是有微軟開發(fā)的一個新的高級語言,用于開發(fā)基于微軟.NET平臺的應用程序。
以上就是關于js底層代碼相關問題的回答。希望能幫到你,如有更多相關問題,您也可以聯(lián)系我們的客服進行咨詢,客服也會為您講解更多精彩的知識和內(nèi)容。
推薦閱讀:
國內(nèi)品牌男裝十大排名js(國內(nèi)男裝十大名牌排名6)
怎么隱藏小紅書發(fā)布過的內(nèi)容(怎么隱藏小紅書發(fā)布過的內(nèi)容和視頻)