緣起
書接上文《從壹開始前后端分離 [ Vue2.0+.NET Core2.1] 十四 ║ VUE 計划書 & 我的前后端開發簡史》,昨天咱們說到了以我的經歷說明的web開發經歷的幾個階段,而且也說到了Vue系列需要講到的知識點,今天就正式開始Code,當然今天的代碼都特別簡單,希望大家慢慢的學習,今天主要講的是JS高級——關於面向對象的語法。
磨刀不誤砍柴工,當然,我在寫這篇之前,或者是寫Vue之前,都在考慮要從何處入手,怎么寫,因為大家肯定有一部分是全棧工程師,都很懂,那我寫的您就可以一目十行,不用看代碼,也有一部分還是專注於后端,前端只是會一些Javascript,或者Jquery,進行一些Dom操作等,最后還有一部分小伙伴是CS模式開發的,我們的QQ群我就了解到一些,所以呢,我就去各個平台看大家是如何講Vue,或者是講MVVM前后端分離的,嗯~~~,我也都能看懂,但是就是不想和他們一樣 [ 這樣會拉仇恨么哈哈 ],當然,不是說我寫的好,因為好多人都是文章直接一上來就Vue-cli搞起來,直接Hello World跑起來,然后就是搞一個TodoList,基本的就這么過去了,感覺既然是寫了,就要從基礎寫起,所以我就想到了先從JS面向對象講起,做個鋪墊,也給大家一個緩沖。大家放心,Vue-cli,Vue-router,Axios,Vuex等等,咱們都有,還有hello world,哈哈哈哈!
這個時候,一定會有好多小伙伴問,既然是Vue,為什么要說JS呢,請看我寫的簡單的代碼(這是Vue定義一個組件的語法):
不要怕看不懂,因為過一段時間就會了
<script> import myHeader from '../components/header.vue' import myFooter from '../components/footer.vue' export default { components: {myHeader, myFooter}, data() { return { id: this.$route.params.id, dat: {}, isShow: true } }, created() { this.getData() }, methods: { getData() { var that = this this.$api.get('Blog/Get/' + this.id, null, r => { r.data.bCreateTime = that.$utils.goodTime(r.data.bCreateTime) this.dat = r.data this.isShow = false }) } }, watch: { '$route'(to, from) { this.dat={} this.isShow = true this.id = to.params.id this.getData() } } } </script>
零、今天要完成淺綠色的部分
一、JS和C#一樣,一切都是對象
1、關於JS函數對象方法的寫法,目前有兩種,不知道大家平時喜歡用哪種,請看:
//這種是直接函數聲明的方法
var id=9;
var brandid=1;
GetGoods();
GetDetail();
GetUsers();
function GetGoods() {
var tmplTrips = new StringBuilder();
$('#DifCountry .cur').removeClass("cur");
//...
}
function GetDetail() {
var tmplTrips = new StringBuilder();
$('#DifCountry .cur').removeClass("cur");
//...
}
function GetUsers() {
var tmplTrips = new StringBuilder();
$('#DifCountry .cur').removeClass("cur");
//...
}
//這一種是對象的寫法 Object.defineProperties(a, { "property": { set property(newValue) { console.log("set property"); return this._property = newValue; }, get property() { console.log("getgsd property"); return this._property; }, enumerable: true, configurable: true }, "name":{ value: "maotr", writable: true, enumerable: true, configurable: true } });
2、對象包含哪些元素
包含 屬性,方法,數據類型(字符串,數字,布爾,數組,對象),在C#中,隨隨便便就是寫出幾個對象,JS中也是如此。
二、定義對象的四種方式
1、通過new關鍵字
格式:new Object();
var obj=new Object(); obj.Name='blog'; obj.address='beijing';
2、嵌套字面量的方法,鍵值對的形式
格式:objectName = {property1:value1, property2:value2,…, propertyN:valueN} 。property是對象的屬性
這個我使用的較多,只要是用來POST傳值的時候。
var obj = { name: 'blog', address: 'beijing', say: function () { alert("hello world"); } }
3、函數表達式,和函數聲明很類似
注意!函數表達式必須先定義,再使用,有上下順序之分;而函數聲明沒有。
//函數聲明(定義和使用沒有先后之分) function obj(){ alert('hi,我是函數聲明'); } //函數表達式(必須先定義聲明,再使用) var obj=function(){
//other things... alert('hi,我是函數表達式方法') }
4、構造函數聲明
function Blog(title,font) { this.title = title, this.font = font, this.read = function () { alert('Hi ,Blog'); } } var blog1 = new Blog('JS學習', 100); alert(blog1.title); blog1.read();
總體來說,
構造函數,和普通函數都是平時用的較多的寫法
//構造函數 function Egperson (name,age) { this.name = name; this.age = age; this.sayName = function () { alert(this.name); } } var person = new Egperson('mike','18'); //this-->person person.sayName(); //'mike' //普通函數 function egPerson (name,age) { this.name = name; this.age = age; this.sayName = function () { alert(this.name); } } egPerson('alice','23'); //this-->window window.sayName(); //'alice'
但是要注意,構造函數和普通函數的區別:
1、在命名規則上,構造函數一般是首字母大寫,普通函數則是遵照小駝峰式命名法
2、構造函數內部的this指向是新創建的person實例,而普通函數內部的this指向調用函數的對象(如果沒有對象調用,默認為window)
3、構造函數內部會創建一個實例,調用普通函數時則不會創建新的對象
這個時候你一定會問了,看着兩種方法很相似呀???
這里引用網友的說法:
我感覺創造實例的原因是因為new ,而不是因為他是“構造函數”,構造函數的名稱首字母大寫是約定。瀏覽器並不會因為函數的首字母是否大寫來判斷這個函數是不是構造函數。普通函數也通過New創建也依舊可以打上構造函數的效果。如果不想用new,也可以加一個return語句。
補充:構造函數返回都是對象。也可以在構造函數中顯示調用return.如果return的值是一個對象,它會代替新創建的對象實例返回。如果返回的值是一個原始類型,它會被忽略,新創建的實例(對象)會被返回。
三、剪不斷理還亂的 this關鍵字
1、這里有一個常見面試題,相信有很多人會亂:
function foo() { var f2 = new foo2(); console.log(f2); //{a: 3} console.log(this); //window return true; } function foo2() { console.log(this); //foo2類型的對象 不是foo2函數 return { a: 3 }; } var f1 = foo(); console.log(f1); // true
大概思路是這樣的;
1、f1調用foo(),然后foo(),又實例化對象foo2,所以,這個時候,f2就是一個foo2()的一個對象,被打印出來;
2、然后foo2(),返回值一個對象{a:3},被賦值給了f2,被打印出來;
3、這個this,就是調用者,也就是window;
4、這個時候foo()的返回值 true,被賦值給f1,被打印出來;
2、深入理解 js this關鍵字
栗子1:
var name = 'blog.vue'; function showName(){ return this.name; } alert(showName()); //blog.vue
大家都知道是指向window全局對象的屬性(變量)name,因為調用showName()實際上就相當於window.showName(),所以this指向window對象。
這里看着有些簡單,但是如果復雜點兒呢,所以這里先引入三個概念:
1、函數名是一個指向函數的指針。
2、函數執行環境(this什么時候初始化):當某個函數第一次被調用時,會創建一個執行環境,並使用this/arguments和其他命名參數的值來初始化函數的活動對象。
3、初始化指向誰:在Javascript中,this關鍵字永遠都指向函數(方法)的所有者。
栗子2
var name = 'The window'; var object = { name:'The object', getNameFunc:function(){ return object1.getNameFunc(); } }; var object1 = { name:'The object1', getNameFunc:function(){ return this.name; } }; alert(object.getNameFunc());//The object1
說明:object1.getNameFunc()相當於是調用object1對象的getNameFunc方法,此時會初始化this關鍵字,而getNameFunc方法的所有者就是object1,this指向object1,所以調用object1.getNameFunc()返回的是object1的name屬性,也就是"The object1"。
3、總結
函數的幾種調用方式:
1.普通函數調用
2.作為方法來調用
3.作為構造函數來調用
4.使用apply、call方法來調用
5.Function.prototype.bind方法
6.es6箭頭函數
請記住一點:誰調用這個函數或方法,this關鍵字就指向誰。
如果你對this以及函數的嵌套字面量有一定的了解了,可以看看下邊這個小Demo。
四、面向對象實例Demo
1、我簡單做了一個小Demo,大家可以看看,當然也可以自己動手試試,特別簡單的,就是鼠標滑過,顯示按鈕,彈窗。
這個代碼我已經到了Git上,地址是,以后每次的小Demo我都會放上去,以備不時之需,Git代碼在文末。
var obj = { data: { books: "", price: 0, bookObj: null }, init: function () { this.bind(); this.popup(); this.show(); }, show: function () { $(".content-title").html(""); $(".content-title").html(this.data.books); $(".content-price").html(this.data.price); }, bind: function () { var that = this; $(".content .content-list ").hover(function () { $(this).find(".see").show(); }, function () { $(this).find(".see").hide(); }); $(".see").click(function () { $(".bg,.popupbox").show(); that.data.bookObj = $(this); }); $(".btn3,.cancel").click(function () { $(".bg,.popupbox").hide(); }); $(".ok").click(function () { var bookItem = that.data.bookObj; var _parice = $(bookItem).data("price"); var _book = $(bookItem).data("book"); that.data.books += _book + ","; that.data.price += parseInt(_parice); that.show(); }); }, popup: function () { var box = $(".popupbox"); var _width = document.documentElement.clientWidth; var _height = document.documentElement.clientHeight; var $width = (_width - box.width()) / 2; var $height = (_height - box.height()) / 2; box.css({ "left": $width, "top": $height }); }, watch: { } }; $(function () { obj.init(); });
這個栗子,就是我們上文中的第二節的第2個方法——通過定義嵌套字面量的形式來寫的,只不過稍微復雜一丟丟(顏值不好,大家多擔待)。
這個時候,你再把這個代碼和上文的開篇的那個Vue寫法對比下:哦!是不是有點兒相近的意思了。嗯!如果你找到了其中的類似處,那恭喜,你已經基本入門啦!
2、單向數據傳輸
從上邊的代碼和動圖你應該能看到,目前這種開發都是單向數據的(是通過Data來控制Dom的展示的),那如何通過操作Dom來控制Data呢?誒~如果你能這么想,那Vue已經事半功倍了。
其實MVVM的核心功能之一就是雙向數據傳輸。
五、結語
今天也是簡簡單單的說了一下,面向對象的一些知識,還有就是如何定義嵌套字面量,this到底如何歸屬的,講的稍微淺顯了一些,后期還需要大量內容豐富,如果你自己寫一遍,你應該已經掌握了如何定義一個對象方法了。這樣可以為以后學習Vue打下基礎。好啦今天的講解暫時到這里辣~明天繼續JS高級的屬性獲取和ES6的一些內容。