一、面向對象-OOD
雖然js面向對象的編程思想已經老話常談了,但了為了文章的完整性,我還是把它加了進來,盡量以不太一樣的方式講述(雖然也沒什么卵不一樣的)。
1、面向對象,首先得有類的概念,沒有類造不出來對象,但是javascript中又沒有類 只有函數的感念,把以大寫字母命名的函數看成創建對象的構造函數,把函數名看成類,那么就可以new一個對象了
//1.1 無參的
function People() {
}
var p = new People();
//javascript為解釋性語言,運行時編譯,所以我們點什么屬性,就會有什么屬性了。
p.name = 'hannimei';
console.log(p.name);
//2.2 來個有參數的
function Student(name, age) {
this.name = name;
this.age = age;
this.say = function () {
return saywhat();
}
//私有函數
function saywhat(){
return this.name+':say what?';
}
return this;
}
var s = new Student('lily', 18);
console.log(s.name);
console.log(s.say());
//2.3 來個factory
function Factory(name,age) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.say = function () {
return obj.name+ ':say what?';
}
return obj;
}
var o = new Factory('factory', 1);
console.log(o.say());
//2.4對象字面方式創建對象
var ob = { Name: "字面量", Age: 18 };
//當然也有字符串字面量、數組字面量這些
var str = 'hello javascript!';
var arr = [1, 2, 3, 4, 5];
2、那么有了類,面向對象同樣不能少的特性就是繼承;js中繼承有各種方式的實現,通過函數原型鏈最常見不過了
天生自帶技能乃是命,如果后來想修煉技能怎么辦,直接點出來就好了嘛;如果不想修煉就想天生自帶,那就得說下prototype了。
function Teacher(schoolname) {
this.schoolname = schoolname;
return this;
}
var t = new Teacher('2b1中');
創建Teacher函數對象t時,t的__proto__指向了一個object,這個的指向其實就是函數的原型(為什么呢?聽我慢慢往下道),如圖:這個object又有兩個屬性,constructor定義了創建它的Teacher函數,__proto__繼續向上指向Object,通過這種對象二叉樹的結構,就標識了這個對象怎么來的和出生都自帶什么技能。
那我們后台想自帶技能就要通過增加t的__proto__指向的那個object默認技能了


從Teacher的監視圖我們看到兩個關鍵的屬性,一個是它的函數原型prototype,測試得知這個東西和上圖的__proto__指向同一個object,那么我們也就知道函數的另一個__proto__是指向它父級的Function的prototype,最終指向Object的prototype
經過上面的調理,我們終於明白了先天靠遺傳,后天靠拼搏這句話的真諦;再試着回味一下這句話
//2.1 直接給prototype添加屬性
function Teacher(schoolname) {
this.schoolname = schoolname;
return this;
}
Teacher.prototype.age = 18;
Teacher.prototype.jiangke = function () {
return '老師開始講課了';
}
var t = new Teacher('2b1中');
console.log(t.age);
console.log(t.schoolname);
console.log(t.jiangke());
//2.2 通過prototype繼承,prototype指向的是一個object,所以我們繼承的話就指向父類new出來的對象就可以了
//這一句代碼引發的長篇大論
function People(name) {
this.name = name;
this.say = function () {
return this.name + ':say what?';
}
return this;
}
function Student(name) {
this.name = name;
}
Student.prototype = new People(Student.name);
var s = new Student('啊彌陀丸');
console.log(s.say());
二、面向數據-DOP
1、初探
js面向數據編程這個概念是阿里什么論壇會上提出來的,簡單的來說就是,大家懶得用js操作DOM元素了,通過直接對數據的賦值修改,然后替換到html模板中,最后直接調用innerHTML顯;舉個例子吧,雖然不夠貼切 也不夠完整,但話糙理不糙,它只是用來說明問題
這就是我們簡陋的購物車,有兩種水果和要購買的個數,通過+/-修改個數
<div id="gwcid">
<p>橘子:<input type="number" value="1" /><input type="button" value="+" onclick="changeEvent('orange');" /></p>
<p>蘋果:<input type="number" value="1" /><input type="button" value="+" onclick="changeEvent('apple');" /></p>
</div>
傳統的方式,我們會操作DOM,然后修改它的value值;但面向數據編程的時候需要的是,得現有一個json model,然后有一個html view,把操作后的屬性值relace到view中,最后innerHTML大功告成。那么這種通用的編程方式的好處自然不言而喻,而且以現在瀏覽器渲染的速度,處理大數據時真是必備良品
var fruits = { orange: 1, apple: 1 };
//模板可以放入html中讀取,此處為了方便
var tpl = '<p>橘子:<input type="number" value="<%orange%>" /><input type="button" value="+" onclick="changeEvent(\'orange\');"/></p><p>蘋果:<input type="number" value="<%apple%>" /><input type="button" value="+" onclick="changeEvent(\'apple\');"/></p>';
function changeEvent(name) {
//操作數據
fruits[name] += 1;
//替換值
var result = tpl.SetValue(fruits);
//innerHTML
document.getElementById('gwcid').innerHTML = result;
}
String.prototype.SetValue = function (json) {
//regex replace
return this.replace(/<%\w+%>?/gi, function (matchs) {
var str = json[matchs.replace(/<%|%>/g, "")];
return str == "undefined" ? "" : str;
});
}
2、開始及結束
經過上面的例子,相信js模板引擎啥的我們也就一並結束了吧,至少現在各種的模板引擎我也沒太深入用,那些官方介紹的話也懶得貼出來了
大勢所趨,現在后端許多核心的思想MVC、依賴注入、模塊化等都被應用到了前段,而且連native的mvvm思想都搬了過來,說到這里,想必各位已經猜到接下來要說的東西--AngularJS,此處以文檔學習為主,理論思想就懶得貼了。
2.1 Expression
<h3>表達式</h3>
<input type="number" ng-model="num1" />+<input type="number" ng-model="num2" />
<p>結果為:{{num1+num2}}</p>
<hr />
<h3>字符串</h3>
<div ng-init="name='lily';age=18">
<p>姓名:{{name}},年齡 {{age}}</p>
</div>
<hr />
<h3>對象</h3>
<div ng-init="student={name:'lucy',age:16}">
<p>姓名:{{student.name}},年齡:{{student.age}}</p>
</div>
<hr />
<h3>數組</h3>
<div ng-init="nums=[1,2,3,4]">
<p>數組[1]:{{nums[1]}}</p>
<p>數組tostring:{{nums.toString()}}</p>
</div>
2.2 ng-
<!--ng-app:初始化AngularJS應用程序;ng-init:初始化應用程序數據。-->
<div ng-init="word='world'">
hello {{word}}
</div>
<!--ng-model:把元素值(比如輸入域的值)綁定到應用程序-->
請輸入:<input type="text" ng-model="input" />
你輸入的是:{{input}}
<!--ng-show:驗證不通過返回ture時顯示-->
<p ng-show="true">可以看見</p>
<p ng-show="false">看不見</p>
<p ng-show="1=1">表達式成立可以看見</p>
<form action="/" method="post" ng-app="" name="form1">
email:<input type="email" name="address" ng-model="email" />
<span ng-show="form1.address.$error.email">請輸入合法的郵箱</span>
<ul>
<li>字段內容是否合法:{{form1.address.$valid}}</li>
<li>表單是否有填寫記錄:{{form1.address.$dirty}}</li>
<li>字段內容是否非法:{{form1.address.$invalid}}</li>
<li>是否觸屏點擊:{{form1.address.$touched}}</li>
<li>是否沒有填寫記錄:{{form1.address.$pristine}}</li>
</ul>
</form>
<!--ng-disabled:是否不可用-->
<button ng-disabled="true">點我!</button>
<!--ng-hide:是否可見-->
<p ng-hide="false">可以看見吧</p>
<!--ng-bind:綁定元素innerText的值-->
<div ng-init="quantity=3;cost=5">
價格:<span ng-bind="quantity*cost"></span>
</div>
<div ng-init="nums2=[10,20,30]">
<p ng-bind="nums2[1]"></p>
</div>
<!--ng-click:事件-->
<div ng-init="count=0;">
count:{{count}}
<br /><button ng-click="count=count+1">+1</button>
</div>
<!--ng-repeat:循環指令-->
<div ng-init="citys=[{name:'北京',val:1},{name:'上海',val:2},{name:'廣州',val:3}]">
<select>
<option ng-repeat="x in citys" ng-bind="x.name" value="{{x.val}}"></option>
</select>
</div>
<!--ng-include:包含html內容-->
<div ng-include="'05service.html'"></div>
<!--自定義指令-->
<!--標簽-->
<runoob-directive></runoob-directive>
<!--屬性-->
<div runoob-directive></div>
<!--類名-->
<div class="runoob-directive"></div>
<script type="text/javascript">
var app = angular.module("myApp", []);
app.directive("runoobDirective", function () {
return {
//restrict: "E", E只限元素調用,A只限屬性調用,C只限類名調用,M只限注釋調用
//replace: true,當為M為注釋時,可見為true
template: "<h1>自定義指令!</h1>"
};
});
</script>
2.3 Scope
<!--ng-controller 指令定義了應用程序控制器;在controller中給$scope添加屬性,view中就可以傳遞過去使用了-->
<div ng-app="myApp">
<div ng-controller="ctrl">
{{name}}<br />
{{say();}}<br />
{{$root.genname}}
</div>
<div ng-controller="ctrl1">
{{$root.genname}}
</div>
</div>
<div id="div2" ng-app="myApp2" ng-controller="ctrl2">
{{name}}
</div>
<script type="text/javascript">
var app = angular.module('myApp', []); //'[]'用來創建依賴,沒有的話 表示繼續用之前創建的
app.controller('ctrl', function ($scope) {
$scope.name = 'scope';
$scope.say = function () { return 'hello,sister' };
});
//rootScope 根作用域,作用在整個app中,可以在各個controller中使用
app.controller('ctrl1', function ($scope, $rootScope) {
$rootScope.genname = '根作用域';
})
var app2 = angular.module('myApp2', []);
app2.controller('ctrl2', function ($scope) {
$scope.name = '另一個作用域了';
})
//手動啟動第二個app,記清作用域哦
angular.bootstrap(document.getElementById('div2'), ['myApp2'])
</script>
2.4 Filter
<!--currency 格式化數字為貨幣格式。
filter 從數組項中選擇一個子集。
lowercase 格式化字符串為小寫。
orderBy 根據某個表達式排列數組。
uppercase 格式化字符串為大寫。-->
<div ng-app="" ng-init="name='lily';citys=[{name:'北京',val:1},{name:'上海',val:2},{name:'廣州',val:3}]">
{{name|uppercase}} <!--表達式中添加-->
<ul>
<li ng-repeat="c in citys|filter:inp|orderBy: 'val'">{{c.name}}</li> <!--指令中過濾-->
</ul>
<input type="text" ng-model="inp"> <!--輸入過濾li-->
</div>
2.5 Service
<div ng-app="myApp" ng-controller="ctrl">
當前url:{{currenturl}}<br />
get請求json數據:{{jsondata}}
自定義服務:{{myservice}}
</div>
<script type="text/javascript">
//自定義服務
angular.module('myApp', []).service('myservice', function () {
this.toStartUpper = function (str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
};
});
angular.module('myApp').controller('ctrl', function ($scope, $timeout, $location, $http, myservice) {
$scope.currenturl = $location.absUrl(); // $location 當前頁面的 URL 地址
$timeout(function () { //$timeout等同於window.setTimeout;$interval等同於window.setInterval
console.log('timeout 執行了');
}, 2000);
//http請求 XMLHttpRequest
$http.get('json.txt').success(function (response) { $scope.jsondata = response; });
$scope.myservice = myservice.toStartUpper('service');
});
</script>
2.6 api
<div ng-app="myapp" ng-controller="ctrl">
是否是字符串:{{isstr}}<br />
是否是數字:{{isnum}}<br />
轉為大寫是:{{strtoupper}}<br />
</div>
<script type="text/javascript">
angular.module('myapp', []).controller('ctrl', function ($scope) {
$scope.str = 'sdfsdf';
$scope.isstr = angular.isString($scope.str);
$scope.strtoupper = angular.uppercase($scope.str);
$scope.isnum = angular.isNumber($scope.str);
});
</script>
2.7 animate
<!--ngAnimate 模型可以添加或移除 class 。
ngAnimate 模型並不能使 HTML 元素產生動畫,但是 ngAnimate 會監測事件,類似隱藏顯示 HTML 元素 ,如果事件發生 ngAnimate 就會使用預定義的 class 來設置 HTML 元素的動畫。-->
<input type="checkbox" ng-model="mycheck">點我隱藏div
<!--添加/移除 class 的指令:
ng-show
ng-hide
ng-class
ng-view
ng-include
ng-repeat
ng-if
ng-switch
ng-show 和 ng-hide 指令用於添加或移除 ng-hide class 的值
其他指令會在進入 DOM 會添加 ng-enter 類,移除 DOM 會添加 ng-leave 屬性
當 HTML 元素位置改變時,ng-repeat 指令同樣可以添加 ng-move 類
-->
<div ng-hide="mycheck"></div>
<script type="text/javascript">
var app = angular.module('myApp', ['ngAnimate']);
</script>
2.8 DI
var app = angular.module('myapp', []);
//注入value
app.value('defaultval', 0);
//factory 注入service
app.factory('sumService', function () {
var factory = {};
factory.sum = function (a, b) {
return a + b
}
return factory;
});
//自定義computeServer服務
app.service('computeServer', function (sumService) {
this.sum = function (a, b) {
return sumService.sum(a, b);
};
});
//provider
app.config(function ($provider) {
$provider.provider('sumService', function () {
this.$get = function () {
var factory = {};
factory.sum = function (a, b) {
return a + b;
}
return factory;
};
});
});
//constant 常量配置
app.constant('save', 'false');
//注入的value
app.controller('ctrl', function ($scope, defaultval) {
$scope.defaultval = defaultval;
});
2.9 route
<body ng-app="myapp">
<ul>
<li><a href="#/">首頁</a></li>
<li><a href="#/product">產品</a></li>
<li><a href="#/about">關於</a></li>
</ul>
<div ng-view></div>
<script type="text/javascript">
//添加route依賴
angular.module('myapp', ['ngRoute'])
///$routeProvider.when(url, {
// template: string, 在 ng-view 中插入簡單的 HTML 內容
// templateUrl: string, templateUrl 插入html模板文件
// controller: string, function 或 array, function、string或數組類型,在當前模板上執行的controller函數,生成新的scope。
// controllerAs: string, string類型,為controller指定別名。
//redirectTo: string, function, 重定向地址
// resolve: object<key, function> 指定當前controller所依賴的其他模塊
// });
.config(['$routeProvider', function ($routeProvider) { //$routeProvider 用來定義路由規則
$routeProvider.when('/', { template: '這是首頁' }) //$routeProvider.when 函數的第一個參數是 URL 或者 URL 正則規則,第二個參數為路由配置對象。
.when('/product', { template: '這是產品' })
.when('/about', { template: '這是關於我們' })
.otherwise({ redirectTo: '/' });
}]);
</script>
</body>
三、面向H5
html5給力之處,無非是javascript大量的api;像以前想要修改url參數不跳轉做標識用,只能用#,有了pushStata 呵呵呵;更或者做webim輪詢服務器,現在windows server12+websocket直接搞起(還是用signalr實在點,裝逼也沒人信);當然 不論是本地數據庫還是websocket更或者是強大的canvas api等等等太多,其實都不如querySelector、querySelectorAll這類的api來的實在(用慣了jquery選擇器的可能都這么想)
那么問題來了,既想寫一套代碼,又想用h5新api的寫法,跟着潮流 不然就out了;那么就需要兼容IE8及下,為他們實現h5這些個常用的api就好了撒
思想已經出來了,但雛形還未跟上,雖然很簡單,但是我還是厚着臉皮寫出來了
<input type="text" id="inputid" name="name" value="none" />
<script type="text/javascript">
if (!window.localStorage) {
document.write('<script src="xxx.js"><\/script>');
//document.write('<script src="jquery-1.9.1.js"><\/script>');
//(function (d) {
// d.query = function (selector) {
// return $(selector)[0];
// }
// Element.prototype.addEvent = function (types, fn) {
// return $(this).bind(types, fn);
// }
//})(document);
}
window.onload = function () {
var obj = document.query('#inputid');
console.log(obj.value);
obj.addEvent('change', function () {
console.log(this.value);
})
};
</script>
越寫越爛,請勿轉載:http://www.cnblogs.com/NotAnEmpty/p/5462268.html
