一.Js的this,{},[]javascript
二.JS的prototype和__proto__java
1.prototype和__proto__的概念chrome
prototype是函數的一個屬性(每一個函數都有一個prototype屬性),這個屬性是一個指針,指向一個對象。它是顯示修改對象的原型的屬性。數組
__proto__是一個對象擁有的內置屬性(請注意:prototype是函數的內置屬性,__proto__是對象的內置屬性),是JS內部使用尋找原型鏈的屬性。app
用chrome和FF均可以訪問到對象的__proto__屬性,IE不能夠。函數
2.new 的過程測試
var Person = function(){};this
var p = new Person();spa
new的過程拆分紅如下三步:prototype
(1) var p={}; 也就是說,初始化一個對象p
(2) p.__proto__ = Person.prototype;
(3) Person.call(p); 也就是說構造p,也能夠稱之爲初始化p
關鍵在於第二步,咱們來證實一下:
var Person = function(){};
var p = new Person();
alert(p.__proto__ === Person.prototype);
這段代碼會返回true。說明咱們步驟2是正確的。
3.示例
複製代碼
var Person = function(){};
Person.prototype.sayName = function() {
alert("My Name is Jacky");
};
Person.prototype.age = 27;
var p = new Person();
p.sayName();
複製代碼
p是一個引用指向Person的對象。咱們在Person的原型上定義了一個sayName方法和age屬性,當咱們執行p.age時,會先在this的內部查找(也就是
構造函數內部),若是沒有找到而後再沿着原型鏈向上追溯。
這裏的向上追溯是怎麼向上的呢?這裏就要使用__proto__屬性來連接到原型(也就是Person.prototype)進行查找。最終在原型上找到了age屬性。
三.js繼承,網上不少人說是5種我所理解的是4種,另一種是在這4種方式基礎上的一種轉變
1.使用對象冒充實現繼承(該種實現方式能夠實現多繼承)
實現原理:讓父類的構造函數成爲子類的方法,而後調用該子類的方法,經過this關鍵字給全部的屬性和方法賦值
function Parent(firstname)
{
this.fname=firstname;
this.age=40;
this.sayAge=function()
{
console.log(this.age);
}
}
function Child(firstname)
{
this.parent=Parent;
this.parent(firstname);
delete this.parent;
this.saySomeThing=function()
{
console.log(this.fname);
this.sayAge();
}
}
var mychild=new Child("李");
mychild.saySomeThing();
2.採用call方法改變函數上下文實現繼承(該種方式不能繼承原型鏈,若想繼承原型鏈,則採用5混合模式)
實現原理:改變函數內部的函數上下文this,使它指向傳入函數的具體對象
function Parent(firstname)
{
this.fname=firstname;
this.age=40;
this.sayAge=function()
{
console.log(this.age);
}
}
function Child(firstname)
{
this.saySomeThing=function()
{
console.log(this.fname);
this.sayAge();
}
this.getName=function()
{
return firstname;
}
}
var child=new Child("張");
Parent.call(child,child.getName());
child.saySomeThing();
3.採用Apply方法改變函數上下文實現繼承(該種方式不能繼承原型鏈,若想繼承原型鏈,則採用5混合模式)
實現原理:改變函數內部的函數上下文this,使它指向傳入函數的具體對象
function Parent(firstname)
{
this.fname=firstname;
this.age=40;
this.sayAge=function()
{
console.log(this.age);
}
}
function Child(firstname)
{
this.saySomeThing=function()
{
console.log(this.fname);
this.sayAge();
}
this.getName=function()
{
return firstname;
}
}
var child=new Child("張");
Parent.apply(child,[child.getName()]);
child.saySomeThing();
4.採用原型鏈的方式實現繼承
function Parent()
{
this.sayAge=function()
{
console.log(this.age);
}
}
function Child(firstname)
{
this.fname=firstname;
this.age=40;
this.saySomeThing=function()
{
console.log(this.fname);
this.sayAge();
}
}
Child.prototype=new Parent();
var child=new Child("張");
child.saySomeThing();
四.jQuery插件的開發包括兩種:
一種是類級別的插件開發,即給jQuery添加新的全局函數,至關於給jQuery類自己添加方法。jQuery的全局函數就是屬於jQuery命名空間的函數,另外一種是對象級別的插件開發,即給jQuery對象添加方法。下面就兩種函數的開發作詳細的說明。
1、類級別的插件開發
類級別的插件開發最直接的理解就是給jQuery類添加類方法,能夠理解爲添加靜態方法。典型的例子就是$.AJAX()這個函數,將函數定義於jQuery的命名空間中。關於類級別的插件開發能夠採用以下幾種形式進行擴展:
1.1 添加一個新的全局函數
添加一個全局函數,咱們只需以下定義:
js代碼
jQuery.foo = function() {
alert('測試');
};
1.2 增長多個全局函數
添加多個全局函數,可採用以下定義:
js代碼
jQuery.foo = function() {
alert('測試');
};
jQuery.bar = function(param) {
alert('測試');
};
調用時和一個函數的同樣的:jQuery.foo();jQuery.bar();或者$.foo();$.bar('bar');
1.3 使用jQuery.extend(object);
js代碼
jQuery.extend({
foo: function() {
alert('測試');
},
bar: function(param) {
alert('測試');
}
});
1.4 使用命名空間
雖然在jQuery命名空間中,咱們禁止使用了大量的javaScript函數名和變量名。可是仍然不可避免某些函數或變量名將於其餘jQuery插件衝突,所以咱們習慣將一些方法封裝到另外一個自定義的命名空間。
js代碼
jQuery.myPlugin = {
foo:function() {
alert('測試');
},
bar:function(param) {
alert('測試');
}
};
採用命名空間的函數仍然是全局函數,調用時採用的方法:
$.myPlugin.foo();
$.myPlugin.bar('baz');
經過這個技巧(使用獨立的插件名),咱們能夠避免命名空間內函數的衝突。
2、對象級別的插件開發
對象級別的插件開發須要以下的兩種形式:、
形式1:
Java代碼
(function($){
$.fn.extend({
pluginName:function(opt,callback){
// 實現的方式在這裏
}
})
})(jQuery);
形式2:
js代碼
(function($) {
$.fn.pluginName = function() {
//實現的方式在這裏
};
})(jQuery);
上面定義了一個jQuery函數,形參是$,函數定義完成以後,把jQuery這個實參傳遞進去.當即調用執行。這樣的好處是,咱們在寫jQuery插件時,也可使用$這個別名,而不會與prototype引發衝突.
2.1 在JQuery名稱空間下申明一個名字
這是一個單一插件的腳本。若是你的腳本中包含多個插件,或者互逆的插件(例如: $.fn.doSomething() 和 $.fn.undoSomething()),那麼你須要聲明多個函數名字。可是,一般當咱們編寫一個插件時,力求僅使用一個名字來包含它的全部內容。咱們的示例插件命名爲「highlight「
Java代碼
$.fn.hilight = function() {
//實現的方式在這裏
};
咱們的插件經過這樣被調用:
$('#myDiv').hilight();
可是若是咱們須要分解咱們的實現代碼爲多個函數該怎麼辦?有不少緣由:設計上的須要;這樣作更容易或更易讀的實現;並且這樣更符合面向對象。 這真是一個麻煩事,把功能實現分解成多個函數而不增長多餘的命名空間。出於認識到和利用函數是javascript中最基本的類對象,咱們能夠這樣作。就像其餘對象同樣,函數能夠被指定爲屬性。所以咱們已經聲明「hilight」爲jQuery的屬性對象,任何其餘的屬性或者函數咱們須要暴露出來的,均可以在"hilight" 函數中被聲明屬性。稍後繼續。
2.2 接受options參數以控制插件的行爲
讓咱們爲咱們的插件添加功能指定前景色和背景色的功能。咱們也許會讓選項像一個options對象傳遞給插件函數。例如:
Java代碼
// plugin definition
$.fn.hilight = function(options) {
var defaults = {
foreground: 'red',
background: 'yellow'
};
var opts = $.extend(defaults, options);
.
};
咱們的插件能夠這樣被調用:
$('#myDiv').hilight({
foreground: 'blue'
});