主頁 > 企業開發 > 原型模式

原型模式

2021-01-29 07:15:59 企業開發

原型模式

原型模式

我們創建的每個函式都有一個 prototype(原型) 屬性,這個屬性是一個指標,指向一個物件,而這個物件的用途是包含可以有特定型別的所有實體共享的屬性和方法,如果按照字面意思來理解,那么 prototype 就是通過呼叫建構式而創建的那個物件實體的原型物件,使用原型物件的好處是可以讓所有物件實體共享它所包含的屬性和方法,換句話說,不必在建構式中定義物件實體的資訊,而是可以將這些資訊直接添加到原型物件中,如下面的例子所示:

function Person() {}

Person.prototype.name = '小明'
Person.prototype.age = 22
Person.prototype.sex = '男'
Person.prototype.sleep = function() { alert(this.name + '睡覺了') }

var person1 = new Person()
person1.sleep()			// '小明睡覺了'

var person2 = new Person()
person2.sleep()			// '小明睡覺了'

console.log(person1.sleep === person2.sleep)	// true

在這里,我們將 sleep() 方法和所有屬性直接添加到了 Personprototype 屬性中,建構式變成了空函式,即使如此,也仍可以通過建構式來創建新物件,而且新物件還具有相同的屬性和方法,但和建構式模式不同的是,新物件的這些屬性和方法是由所有實體共享的,換句話說, person1 person2 訪問的是同一組屬性和同一個 sleep() 函式,要理解原型模式的作業原理,必須先理解 ES5 中原型物件的性質,

理解原型物件

? 無論什么時候,只要創建了一個新函式,就會根據一組特定的規則為該函式創建一個 prototype 屬性,這個屬性指向函式的原型物件,在默認情況下,所有原型物件都會自動獲得一個 constructor (建構式)屬性,這個屬性包含一個指向 prototype 屬性所在函式的指標,就拿前面的例子來說, Person.prototype.constructor 指向 Person ,而通過這個建構式,我們還可繼續為原型物件添加其他屬性和方法,
? 創建了自定義的建構式之后,其原型物件默認只會取得 constructor 屬性;至于其他方法,則都是從 Object 繼承而來的,當呼叫建構式創建一個新實體后,該實體的內部將包含一個指標(內部屬性),指向建構式的原型物件,ECMA-262第5版中管這個指標叫 [[Prototype]],雖然在腳本中沒有標準的訪問方式訪問 [[Prototype]] ,但是在 Firefox、 Safari 和 Chrome 在每個物件上都支持一個屬性 __proto__;而在其它實作中,這個屬性對腳本則是完全不可見的,不過要明確的真正重要的一點就是,在這個連接存在于實體與建構式的原型物件之間,而不是存在于實體與建構式之間,
? 以前面使用 Person 建構式和 Person.prototype 創建實體的代碼為例,下圖展示了各個物件之間的關系,

prototype

? 上圖展示了 Person 建構式、Person 的原型屬性以及 Person 現有的兩個實體之間的關系,在此,Person.prototype 指向了原型物件,而 Person.prototype.constructor 又指回了 Person,原型物件中除了包含 constructor 屬性之外,還包括后來添加的其他屬性, Person的每個實體—— person1person2 都包含了一個內部屬性,該屬性僅僅指向了 Person.prototype,換句話說,它們與建構式沒有直接的關系,此外,要格外注意的是,雖然這兩個實體都不包含屬性和方法,但我們卻可以呼叫 person1.sleep(),這是通過查找物件屬性的程序來實作的,
? 雖然在所有實作中都無法訪問到 [[Prototype]],但可以通過 isPrototypeOf() 方法來確定物件之間是否存在這種關系,從本質上講,如果 [[Prototype]] 指向呼叫 isPrototype() 方法的物件(Person.prototype),那么這個方法就回傳 true

console.log(Person.prototype.isPrototypeOf(person1))	// true
console.log(Person.prototype.isPrototypeOf(person2))	// true

? 這里,用原型物件的 isPrototype() 方法測驗了 person1person2,因為它們內部都有一個指向 Person.prototype 的指標,因此都回傳了 true

ES55 增加了一個新方法,叫 Object.getPrototypeOf(),在所有支持的實作中,這個方法回傳 [[Prototype]] 的值,例如:

console.log(Object.getPrototype(person1) === Person.prototype)	// true
console.log(Object.getPrototype(person1).name)		// 小明

? 這里的第一行代碼只是確定 Object.getProtitypeOf() 回傳的物件實際就是這個物件的原型,這第二行代碼取得了原型物件中的 name 屬性的值,也就是 ‘小明’ ,使用 Object.getPrototypeOf() 可以方便地取得一個物件得原型,而這在利用原型實作繼承得情況下是非常重要的,
? 每當代碼讀取某個物件得某個屬性時,都會執行一次搜索,目標是具有給定名字得屬性,搜索首先從物件實體本身開始,如果在實體中找到了具有給定名字得屬性,則回傳該屬性得值;如果沒有找到,則繼續搜索指標指向得原型物件,在原型物件中查找具有給定名字得屬性,如果在原型物件中找到了這個屬性,則回傳該屬性得值,也就是說,在我們呼叫 person1.name 的時候,會先后執行兩次搜索,

person1.name

這句代碼的內部執行程序如下:

graph TD START([開始])-->A[搜索實體 person1 的屬性] A-->B{找到name屬性}-->|是|C[回傳name屬性值]-->END([結束]) B-->|否|E[搜索實體 person1 的原型屬性] E-->F{找到name屬性}-->|是|C F-->|否|G[回傳undefined]-->END

首先,決議器會尋找實體 person1 的屬性 name

找到了,它就回傳 name 對應的屬性值

沒找到,它就會執行第二次搜索,搜索實體 person1 的內部屬性 [[Prototype]] 指向的原型物件是否存在 name 屬性

找到了,回傳 name 對應的屬性值

沒找到,回傳 undefined

如果實體 person1 存在 name 屬性且它內部 [[Prototype]] 指向的原型物件同樣存在 name 屬性,它會先尋找實體本身的屬性 name,找到了后就不會再次執行第二次對原型物件搜索了,即若實體本身存在我們給定的屬性名,就算它指向的原型物件存在該屬性名,也只會回傳實體本身的屬性值,代碼如下:

function Person() {}
Person.prototype.name = '小明'

var person1 = new Person()
person1.name = '小紅'
console.log(person1.name)		// 小紅
var perspn2 = new Person()
console.log(person2.name)		// 小明

? 雖然可以通過物件實體訪問保存在原型中的值,但卻不能通過物件實體重寫原型中的值,如果我們在實體中添加了一個屬性,而該屬性與實體原型中的一個屬性同名,那我們就在實體中創建該屬性,該屬性將會屏蔽原型中的那個屬性,

? 不過,使用 delete 運算子則可以完全洗掉實體屬性,從而讓我們重新訪問原型中的屬性,如下所示:

function() {}
Person.prototype.name = '小明'

var person1 = new Person()
var person2 = new Person()

person1.name = '小紅'
console.log(person1.name)	// 小紅	來自實體本身的 name 屬性
console.log(person2.name)	// 小明	來自原型物件的 name 屬性

delete person1.name			// 移除了實體 person1 的屬性 name
console.log(person1.name)	// 小明	來自實體本身的 name 屬性

? 在這個修改的例子中,使用了 delete 運算子 移除了 person1.name,之前它保存的實體 name 屬性 屏蔽了同名的原型屬性,把它移除后,就恢復了對原型屬性 name 的連接,因此,接下來再呼叫 person1.name 時,回傳的就是原型中的 name 的值了,

? 使用 hasOwnProperty() 方法可以檢測一個屬性是存在于實體中,還是存在于原型中,這個方法(從Object繼承而來的)只在給定屬性存在于物件實體中時,才會回傳 true

function Person() {}

Person.prototype.name = '小明'

var person1 = new Person()
var person2 = new Person()

person2.name = '小紅'

console.log(person1.hasOwnProperty('name'))	// false	非實體本身的屬性
console.log(person2.hasOwnProperty('name'))	// true		實體本身的屬性

delete person2.name			// 移除實體 person2 的屬性 name
console.log(person2.hasOwnProperty('name'))	// false	非實體本身的屬性

? 通過使用 hasOwnProperty() 方法,訪問的是實體屬性還是原型物件的屬性就一清二楚了,

原型與 in 運算子

? 有兩種方式使用 in 運算子:單獨使用和在 for-in 回圈中使用,在單獨使用時,in 運算子會在通過物件能夠訪問給定屬性時回傳 true,無論該屬性存在于實體中還是原型中,

function Person() {}

Person.prototype.name = '小明'

var person1 = new Person()
var person2 = new Person()

person2.name = '小紅'
console.log(person1.hasOwnProperty('name'))		// false	name 屬性來自原型物件
console.log(person2.hasOwnProperty('name'))		// true		name 屬性來自實體本身
console.log('name' in person1)		// true		person1 實體本身 或者 原型物件有 name 屬性
console.log('name' in person2)		// true		person2 實體本身 或者 原型物件有 name 屬性

delete person2.name		// 移除了實體 person2 的屬性 name

console.log('name' in person2)		// true		person2 實體本事的屬性被移除,但是原型物件仍舊有屬性 name

? 在以上代碼執行的整個程序中, name 屬性要么在實體本身訪問到的,要么在原型物件上訪問到的,無論該屬性存在于實體中還是原型物件中,使用 ’name‘ in person2 始終都會回傳 true
? 同使使用 hasOwnProperty() 方法和 in 運算子,就可以確定該屬性到底時存在于物件中,還是存在于原型中:

function hasPrototypeOrProperty(object, propertyName){
	// 判斷該物件以及它的原型物件是否包含該屬性
	if(propertyName in object){
		// 若存在則判斷它是否為實體本身屬性
		if(object.hasOwnProperty(propertyName)){
			// 若為實體屬性則:
			console.log(propertyName + '是' + '實體本身的屬性')
		// 否則:
		}else {
			console.log(propertyName + '是' + '原型物件的屬性')
		}
	// 若該物件不存在該屬性
	}else {
		console.log('該物件不存在屬性' + propertyName)
	}
}

function Person(){}
Person.prototype.name = '小明'

var person1 = new Person()
var person2 = new Person()
person2.name = '小紅'

hasPrototypeOrProperty(person1, 'name')	// name是原型物件的屬性
hasPrototypeOrProperty(person2, 'name')	// name是實體本身的屬性
hasPrototypeOrProperty(person1, 'abcd')	// 該物件不存在屬性abcd

? 在使用 for-in 回圈時,回傳的是所有能夠通過物件訪問的、可列舉的屬性,其中既包括存在于實體中的屬性,也包括存在于原型中的屬性,屏蔽了原型中不可列舉的屬性(即將[[Enumerable]] 標記為 false 的屬性)的實體屬性也會在 for-in 回圈中回傳,因為根據規定,所有開發人員定義的屬性都是可被列舉的——只有在 IE8 以及更早的版本中例外,

? IE 早期版本的實作中存在一個 bug,即屏蔽不可列舉的屬性的實體依舊不會在 for-in 回圈中,例如:

var obj = {
	toString: function() {}
}

for(var prop in obj){
	if(prop === 'toString') {
		console.log('找到了toString')	// 在IE中不會顯示
	}
}

? 當以上代碼運行時,應該在控制臺中輸出 ‘hello’ 的字串,實體中的屬性 toString 屏蔽了原型中(不可被列舉)的 toString 屬性,在 IE 中,由于其實作認為原型的 toString 屬性被打上了 [[Enumerable]] 的標記,因此跳過了該屬性,該 bug 會影響默認不可被列舉的所有屬性和方法,包括:hasOwnProperty(),hasOwnProperty(),propertyIsEnumerable(),toLocaleString(),toString(),valueOf(),ES55 也將 constructorprototype 屬性的 [[Enumerble]] 特性設定為 false,但并不是所有瀏覽器都照此實作,

? 要取得物件上所有可列舉的實體屬性,可以使用 ES55Object.keys() 方法,這個方法接收一個物件作為引數,回傳一個包含所有可列舉的字串陣列,例如:

function Person() {}
Person.prototype.name = '小明'
Person.prototype.age = 22
Person.prototype.sex = '男'

var person = new Person()

console.log(Object.keys(Person.prototype))		// ["name", "age", "sex"]
// 并不是所有的瀏覽器都能訪問到 __proto__ 屬性
console.log(Object.keys(person.__proto__))		// ["name", "age", "sex"]

person.name = '小紅'
person.age = 22
console.log(Object.keys(person))		// ["name", "age"]

? 如果想要得到所有實體屬性,無論它是否可列舉,都可以使用 Object.getOwnPropertyNames() 方法?,以下方法中回傳的陣列包含了不可被列舉的屬性 constructor

var keys = Object.getOwnPropertyNames(Persone.prototype)
console.log(keys)		//  ["constructor", "name", "age", "sex"]

更簡單的原型語法

? 前面的例子每添加一個屬性和方法就要敲一遍 Person.prototype,為了減少不必要的輸入,也為了從視覺上更好地封裝原型的功能,更常見的做法時用一個包含所有屬性和方法的物件字面量來重寫整個原型物件,如下面所示:

function Person(){}
Person.prototype = {
	name: '小明',
	age: 22,
	sex: '男',
	sleep: function() { alert(this.name + '睡覺了') }
}

? 在上面的代碼中,將 Person.protoyepe 設定成一個新的物件,但是這種方式生成的原型物件中的屬性 constructor 屬性將不再指向 Person 了,每一次創建一個函式時,就會同使創建它的 prototype 物件,該物件也會自動獲得 constructor 屬性,這個屬性指向了新創建的那個函式,在這里也就時指向了 Person,當我們用字面量的方式,其實就是完全覆寫掉了原來的 prototype 物件,因此 constructor 屬性也就變成了新物件的 constructor 屬性(指向了 Object 建構式),不再指向 Person 函式,此時,盡管 instanceof 運算子還能回傳正確的結果,但是通過 constructor 已經無法確定物件的型別了,如下所示:

var person = new Person()
console.log(person instanceof Object)			// true
console.log(person instanceof Person) 			// true
console.log(person.constructor === Person) 	// false
console.log(person.constructor === Object)			// true

? 在此,用 instanceof 運算子測驗了 ObjectPerson 仍然回傳 true,但是 constructor 屬性則等于 Object 而不等于 Person 了,為了解決這種問題,可以在字面量里面定義它的屬性 constructor 的指向:

function Person() {}
Person.prototype = {
	constructor: Person,
	name: '小明',
	age: 22,
	sex: '男',
	sleep: function() { alert(this.name + '睡覺了') }
}

? 以上代碼特意包含了一個 constructor 屬性,并將它的值設定為 Person,從而確保了通過該屬性能夠訪問到正確的值,

? 注意,以這種方式重設 constructor 屬性會導致它的 [[Enumerable]] 特性被設定為 true,默認情況下,原生的 constructor 是不可被列舉的,因此如果兼容 ES5JavaScript 引擎的話,可以這么做:

function Person() {}
Person.prototype = {
	name: '小明',
	age: 22,
	sex: '男',
	sleep: function() { alert(this.name + '睡覺了') }
}
Object.defineProperty(Person.prototype, 'constructor', {
	enumerable: false,
	value: Person
})

原型的動態性

? 由于在原型中查找值得程序是一次搜索,因此我們對原型物件所有的任何修改都能夠立即從實力上反映出來——即使是先創建了實體后修改原型也照樣如此:

var person = new Person()

Person.prototype.sleep = function() { alert('月亮不睡我不睡') }

person.sleep()	// 月亮不睡我不睡

? 以上代碼先創建了 Person 的一個實體,并將其保存在 person 中,然后,下一條陳述句在 Person.prototype 中添加了一個方法 sleep(), 即使 **person **是在添加新方法之前創建的,但它仍然可以訪問這個新定義的方法,其原因可以歸結為實體與原型之間的松散連接關系,當我們呼叫 person.sleep() 時,首先會在實體中搜索名為 sleep 屬性,在沒有找到的情況下,會繼續搜索原型,因為實體與原型之間的連bi接不過只是一個指標,而非一個副本,因此就可以在原型找到新的 sleep 屬性并回傳保存在那里的函式,

? 盡管可以隨時為原型添加屬性和方法,并且修改能夠立即在所有物件實體中反映出來,但如果是重寫整個原型物件,那么情況就不一樣了,我們知道,呼叫建構式時會為實體添加一個指向最初原型的 [[Prototype]] 指標,而把原型修改為另外一個物件就等于切斷了建構式與最初原型之間的聯系,

function() {}
var person = new Person()
Person.prototype = {
	constructor: Person,
	name: '小明'
}
console.log(person.name)	// undefined

? 在這個例子中,先創建了 Person 的一個實體,然后又重寫了其原型物件,然后再呼叫 person.name 時無法找到該屬性,因為 person 指向的原型中不包含以該名字命名的屬性,

重寫原型物件之前:

prototype2

重寫原型物件之后:

prototype2

? 從上圖可以看出,重寫原型物件切斷了現有原型與任何之前已經存在的物件實體之間的聯系,它指向仍舊是最初的原型物件,

原生物件的原型

? 原型模式的重要性不僅體現再創建自定義型別方面,就連所有原生的參考型別,都是采用這種模式創建的,所有原生參考型別(Object、Array、Srting等等) 都在其建構式的原型上定義了方法,例如,再 **Array.prototype **中可以找到 sort() 方法,而在 String.prototype 中可以找到 subtring() 方法,如下所示:

console.log(typeof Array.prototype.sort)			// function
console.log(typeof String.prototype.substring)		// function

? 通過原生物件的原型,不僅可以取得所有默認方法的參考,而且也可以定義新方法,可以修改自定義物件的原型一樣修改原生物件的原型,因此可以隨時添加方法,下面的代碼就給基本包裝型別 String 添加了一個 startWidth() 的方法,

String.prototype.startWidth = function(text) {
	return this.indexOf(text) === 0
}
var msg = 'Hello world!'
console.log(msg.startWidth('Hello'))	// true

? 這里新定義的 startWidth() 方法會在傳入的文本位于一個字串開始時回傳 true,既然方法被添加給了 String.prototype,那么當前環境中的所有字串都可以呼叫它,由于 msg 是字串,而且后臺會呼叫 String 基本包裝函式創建這個字串,因此通過 **msg **就可以呼叫 startWIdth() 方法,

? 盡管可以這樣做,但并不推薦在產品化的程式中修改原生物件的原型,如果因某個實作中缺少某個方法,就在原生物件的原型中添加這個方法,那么當在另一個支持該方法的實作中運行代碼時,就可能導致命名沖突,而且,這樣做也可能意外地重寫原生方法,

原型物件的問題

? 原型物件也不是沒有缺點,首先,它省略了建構式船體初始化引數這一環節,結果所有實體在默認情況下都將取得相同的屬性值,雖然這會在某種程度上帶來一些不方便,但還不是原型的最大的問題,原型模式的最大問題時由其共享的本性所導致的,

? 原型中所有屬性是被很多實體共享的,這種共享對于函式非常合適,對于那些包含基本值得屬性倒也說得過去,畢竟(如前面得例子所示),通過在實體上添加一個同名屬性,可以隱藏原型中的對應屬性,然而,對于包含參考型別值的屬性來說,問題就比較突出了,

function Person(){}
Person.prototype = {
	constructor: Person,
	name: '小明',
	age: 22,
	friends: ['小紅', '小美'],
	sleep: function() { alert(this.name + '睡覺了') }
}

var person1 = new Person()
var person2 = new Person()

person1.friends.push('小敏')

console.log(person1.friends)	// ["小紅", "小美", "小敏"]
console.log(person2.friends)	// ["小紅", "小美", "小敏"]
console.log(person1.friends === person2.friends)	// true

? 在此,Person.prototype 物件有一個名為 friends 的屬性,該屬性包含了一個字串陣列,然后,創建了 Person 的兩個實體,接著,修改了 person1.friendsp 參考的陣列,想陣列中添加了一個字串,由于 friends 陣列存在于 Person.prototype 而非 person1中,所以剛剛提到的修改也會通過 person2.friends (與 person1.friends 指向同一個陣列)反映出來,加入我們的初衷就是像這樣在所有實體中共享一個陣列,那么沒什么問題,可是,實體一般都是要有屬于自己的全部屬性的,而這個問題正是很少看到有人單獨使用原型模式的原因所在,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/253893.html

標籤:JavaScript

上一篇:溫習資料演算法—js滑塊驗證碼

下一篇:建構式+原型模式

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more