• 淡扯javascript编程思想


    一、面向对象-OOD

      虽然js面向对象的编程思想已经老话常谈了,但了为了文章的完整性,我还是把它加了进来,尽量以不太一样的方式讲述(虽然也没什么卵不一样的)。

      1、面向对象,首先得有类的概念,没有类造不出来对象,但是javascript中又没有类 只有函数的感念,把以大写字母命名的函数看成创建对象的构造函数,把函数名看成类,那么就可以new一个对象了

     1 //1.1 无参的
     2 function People() {
     3  
     4 }
     5 var p = new People();
     6 //javascript为解释性语言,运行时编译,所以我们点什么属性,就会有什么属性了。
     7 p.name = 'hannimei';
     8 console.log(p.name);
     9 //2.2 来个有参数的
    10 function Student(name, age) {
    11     this.name = name;
    12     this.age = age;
    13     this.say = function () {
    14         return saywhat();
    15     }<br>  //私有函数<br>    function saywhat(){<br>        return this.name+':say what?';<br>    }
    16     return this;
    17 }
    18 var s = new Student('lily', 18);
    19 console.log(s.name);
    20 console.log(s.say());
    21 //2.3 来个factory
    22 function Factory(name,age) {
    23     var obj = new Object();
    24     obj.name = name;
    25     obj.age = age;
    26     obj.say = function () {
    27         return obj.name+ ':say what?';
    28     }
    29     return obj;
    30 }
    31 var o = new Factory('factory', 1);
    32 console.log(o.say());
    33  
    34 //2.4对象字面方式创建对象
    35 var ob = { Name: "字面量", Age: 18 };
    36 //当然也有字符串字面量、数组字面量这些
    37 var str = 'hello javascript!';
    38 var arr = [1, 2, 3, 4, 5];

    2、那么有了类,面向对象同样不能少的特性就是继承;js中继承有各种方式的实现,通过函数原型链最常见不过了

          天生自带技能乃是命,如果后来想修炼技能怎么办,直接点出来就好了嘛;如果不想修炼就想天生自带,那就得说下prototype了。

    1 function Teacher(schoolname) {
    2             this.schoolname = schoolname;
    3             return this;
    4         }
    5 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

     

      经过上面的调理,我们终于明白了先天靠遗传,后天靠拼搏这句话的真谛;再试着回味一下这句话

     1 //2.1 直接给prototype添加属性
     2 function Teacher(schoolname) {
     3     this.schoolname = schoolname;
     4     return this;
     5 }
     6 Teacher.prototype.age = 18;
     7 Teacher.prototype.jiangke = function () {
     8     return '老师开始讲课了';
     9 }
    10 var t = new Teacher('2b1中');
    11 console.log(t.age);
    12 console.log(t.schoolname);
    13 console.log(t.jiangke());
    14  
    15 //2.2 通过prototype继承,prototype指向的是一个object,所以我们继承的话就指向父类new出来的对象就可以了
    16 //这一句代码引发的长篇大论
    17 function People(name) {
    18     this.name = name;
    19     this.say = function () {
    20         return this.name + ':say what?';
    21     }
    22     return this;
    23 }
    24 function Student(name) {
    25     this.name = name;
    26 }
    27 Student.prototype = new People(Student.name);
    28 var s = new Student('啊弥陀丸');
    29 console.log(s.say());

    二、面向数据-DOP

      1、初探

      js面向数据编程这个概念是阿里什么论坛会上提出来的,简单的来说就是,大家懒得用js操作DOM元素了,通过直接对数据的赋值修改,然后替换到html模板中,最后直接调用innerHTML显;举个例子吧,虽然不够贴切 也不够完整,但话糙理不糙,它只是用来说明问题

      这就是我们简陋的购物车,有两种水果和要购买的个数,通过+/-修改个数

    1 <div id="gwcid">
    2     <p>橘子:<input type="number" value="1" /><input type="button" value="+" onclick="changeEvent('orange');" /></p>
    3     <p>苹果:<input type="number" value="1" /><input type="button" value="+" onclick="changeEvent('apple');" /></p>
    4 </div>

      传统的方式,我们会操作DOM,然后修改它的value值;但面向数据编程的时候需要的是,得现有一个json model,然后有一个html view,把操作后的属性值relace到view中,最后innerHTML大功告成。那么这种通用的编程方式的好处自然不言而喻,而且以现在浏览器渲 染的速度,处理大数据时真是必备良品

     1 var fruits = { orange: 1, apple: 1 };<br>//模板可以放入html中读取,此处为了方便
     2 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>';
     3 function changeEvent(name) {
     4     //操作数据
     5     fruits[name] += 1;
     6     //替换值
     7     var result = tpl.SetValue(fruits);
     8     //innerHTML
     9     document.getElementById('gwcid').innerHTML = result;
    10 }
    11  
    12 String.prototype.SetValue = function (json) {
    13     //regex replace
    14     return this.replace(/<%\w+%>?/gi, function (matchs) {
    15         var str = json[matchs.replace(/<%|%>/g, "")];
    16         return str == "undefined" ? "" : str;
    17     });
    18 }

    2、开始及结束

        经过上面的例子,相信js模板引擎啥的我们也就一并结束了吧,至少现在各种的模板引擎我也没太深入用,那些官方介绍的话也懒得贴出来了

        大势所趋,现在后端许多核心的思想MVC、依赖注入、模块化等都被应用到了前段,而且连native的mvvm思想都搬了过来,说到这里,想必各位已经猜到接下来要说的东西--AngularJS,此处以文档学习为主,理论思想就懒得贴了。

      2.1 Expression

     1 <h3>表达式</h3>
     2 <input type="number" ng-model="num1" />+<input type="number" ng-model="num2" />
     3 <p>结果为:{{num1+num2}}</p>
     4 <hr />
     5 <h3>字符串</h3>
     6 <div ng-init="name='lily';age=18">
     7     <p>姓名:{{name}},年龄 {{age}}</p>
     8 </div>
     9 <hr />
    10 <h3>对象</h3>
    11 <div ng-init="student={name:'lucy',age:16}">
    12     <p>姓名:{{student.name}},年龄:{{student.age}}</p>
    13 </div>
    14 <hr />
    15 <h3>数组</h3>
    16 <div ng-init="nums=[1,2,3,4]">
    17     <p>数组[1]:{{nums[1]}}</p>
    18     <p>数组tostring:{{nums.toString()}}</p>
    19 </div>

      2.2 ng-

     1 <!--ng-app:初始化AngularJS应用程序;ng-init:初始化应用程序数据。-->
     2 <div ng-init="word='world'">
     3     hello {{word}}
     4 </div>
     5  
     6 <!--ng-model:把元素值(比如输入域的值)绑定到应用程序-->
     7 请输入:<input type="text" ng-model="input" />
     8 你输入的是:{{input}}
     9  
    10 <!--ng-show:验证不通过返回ture时显示-->
    11 <p ng-show="true">可以看见</p>
    12 <p ng-show="false">看不见</p>
    13 <p ng-show="1=1">表达式成立可以看见</p>
    14 <form action="/" method="post" ng-app="" name="form1">
    15     email:<input type="email" name="address" ng-model="email" />
    16     <span ng-show="form1.address.$error.email">请输入合法的邮箱</span>
    17     <ul>
    18         <li>字段内容是否合法:{{form1.address.$valid}}</li>
    19         <li>表单是否有填写记录:{{form1.address.$dirty}}</li>
    20         <li>字段内容是否非法:{{form1.address.$invalid}}</li>
    21         <li>是否触屏点击:{{form1.address.$touched}}</li>
    22         <li>是否没有填写记录:{{form1.address.$pristine}}</li>
    23     </ul>
    24 </form>
    25  
    26 <!--ng-disabled:是否不可用-->
    27 <button ng-disabled="true">点我!</button>
    28  
    29 <!--ng-hide:是否可见-->
    30 <p ng-hide="false">可以看见吧</p>
    31  
    32 <!--ng-bind:绑定元素innerText的值-->
    33 <div ng-init="quantity=3;cost=5">
    34     价格:<span ng-bind="quantity*cost"></span>
    35 </div>
    36 <div ng-init="nums2=[10,20,30]">
    37     <p ng-bind="nums2[1]"></p>
    38 </div>
    39  
    40 <!--ng-click:事件-->
    41 <div ng-init="count=0;">
    42     count:{{count}}
    43     <br /><button ng-click="count=count+1">+1</button>
    44 </div>
    45  
    46 <!--ng-repeat:循环指令-->
    47 <div ng-init="citys=[{name:'北京',val:1},{name:'上海',val:2},{name:'广州',val:3}]">
    48     <select>
    49         <option ng-repeat="x in citys" ng-bind="x.name" value="{{x.val}}"></option>
    50     </select>
    51 </div>
    52  
    53 <!--ng-include:包含html内容-->
    54 <div ng-include="'05service.html'"></div>
    55  
    56 <!--自定义指令-->
    57 <!--标签-->
    58 <runoob-directive></runoob-directive>
    59 <!--属性-->
    60 <div runoob-directive></div>
    61 <!--类名-->
    62 <div class="runoob-directive"></div>
    63  
    64 <script type="text/javascript">
    65     var app = angular.module("myApp", []);
    66     app.directive("runoobDirective", function () {
    67         return {
    68             //restrict: "E", E只限元素调用,A只限属性调用,C只限类名调用,M只限注释调用
    69             //replace: true,当为M为注释时,可见为true
    70             template: "<h1>自定义指令!</h1>"
    71         };
    72     });
    73 </script>

      2.3 Scope

     1 <!--ng-controller 指令定义了应用程序控制器;在controller中给$scope添加属性,view中就可以传递过去使用了-->
     2 <div ng-app="myApp">
     3     <div ng-controller="ctrl">
     4         {{name}}<br />
     5         {{say();}}<br />
     6         {{$root.genname}}
     7     </div>
     8     <div ng-controller="ctrl1">
     9         {{$root.genname}}
    10     </div>
    11 </div>
    12  
    13 <div id="div2" ng-app="myApp2" ng-controller="ctrl2">
    14     {{name}}
    15 </div>
    16 <script type="text/javascript">
    17     var app = angular.module('myApp', []); //'[]'用来创建依赖,没有的话 表示继续用之前创建的
    18     app.controller('ctrl', function ($scope) {
    19         $scope.name = 'scope';
    20         $scope.say = function () { return 'hello,sister' };
    21     });
    22     //rootScope 根作用域,作用在整个app中,可以在各个controller中使用
    23     app.controller('ctrl1', function ($scope, $rootScope) {
    24         $rootScope.genname = '根作用域';
    25     })
    26     var app2 = angular.module('myApp2', []);
    27     app2.controller('ctrl2', function ($scope) {
    28         $scope.name = '另一个作用域了';
    29     })
    30     //手动启动第二个app,记清作用域哦
    31     angular.bootstrap(document.getElementById('div2'), ['myApp2'])
    32 </script>

      2.4 Filter

     1 !--currency 格式化数字为货币格式。
     2 filter  从数组项中选择一个子集。
     3 lowercase   格式化字符串为小写。
     4 orderBy 根据某个表达式排列数组。
     5 uppercase   格式化字符串为大写。-->
     6 <div ng-app="" ng-init="name='lily';citys=[{name:'北京',val:1},{name:'上海',val:2},{name:'广州',val:3}]">
     7     {{name|uppercase}}  <!--表达式中添加-->
     8     <ul>
     9         <li ng-repeat="c in citys|filter:inp|orderBy: 'val'">{{c.name}}</li>  <!--指令中过滤-->
    10     </ul>
    11     <input type="text" ng-model="inp">  <!--输入过滤li-->
    12 </div>

      2.5 Service

     1 <div ng-app="myApp" ng-controller="ctrl">
     2     当前url:{{currenturl}}<br />
     3     get请求json数据:{{jsondata}}
     4     自定义服务:{{myservice}}
     5 </div>
     6 <script type="text/javascript">
     7     //自定义服务
     8     angular.module('myApp', []).service('myservice', function () {
     9         this.toStartUpper = function (str) {
    10             return str.substring(0, 1).toUpperCase() + str.substring(1);
    11         };
    12     });
    13  
    14     angular.module('myApp').controller('ctrl', function ($scope, $timeout, $location, $http, myservice) {
    15         $scope.currenturl = $location.absUrl();  // $location 当前页面的 URL 地址
    16         $timeout(function () {  //$timeout等同于window.setTimeout;$interval等同于window.setInterval
    17             console.log('timeout 执行了');
    18         }, 2000);<br>     //http请求 XMLHttpRequest
    19         $http.get('json.txt').success(function (response) { $scope.jsondata = response; });
    20         $scope.myservice = myservice.toStartUpper('service');
    21     });
    22 </script>

      2.6 api

     1 <div ng-app="myapp" ng-controller="ctrl">
     2     是否是字符串:{{isstr}}<br />
     3     是否是数字:{{isnum}}<br />
     4     转为大写是:{{strtoupper}}<br />
     5 </div>
     6 <script type="text/javascript">
     7     angular.module('myapp', []).controller('ctrl', function ($scope) {
     8         $scope.str = 'sdfsdf';
     9         $scope.isstr = angular.isString($scope.str);
    10         $scope.strtoupper = angular.uppercase($scope.str);
    11         $scope.isnum = angular.isNumber($scope.str);
    12     });
    13 </script>

      2.7 animate

     1 <!--ngAnimate 模型可以添加或移除 class 。
     2 ngAnimate 模型并不能使 HTML 元素产生动画,但是 ngAnimate 会监测事件,类似隐藏显示 HTML 元素 ,如果事件发生 ngAnimate 就会使用预定义的 class 来设置 HTML 元素的动画。-->
     3 <input type="checkbox" ng-model="mycheck">点我隐藏div
     4 <!--添加/移除 class 的指令:
     5         ng-show
     6         ng-hide
     7         ng-class
     8         ng-view
     9         ng-include
    10         ng-repeat
    11         ng-if
    12         ng-switch
    13     ng-show 和 ng-hide 指令用于添加或移除 ng-hide class 的值
    14     其他指令会在进入 DOM 会添加 ng-enter 类,移除 DOM 会添加 ng-leave 属性
    15     当 HTML 元素位置改变时,ng-repeat 指令同样可以添加 ng-move 类
    16     -->
    17 <div ng-hide="mycheck"></div>
    18 <script type="text/javascript">
    19     var app = angular.module('myApp', ['ngAnimate']);
    20 </script>

      2.8 DI

     1 var app = angular.module('myapp', []);
     2 //注入value
     3 app.value('defaultval', 0);
     4  
     5 //factory 注入service
     6 app.factory('sumService', function () {
     7     var factory = {};
     8  
     9     factory.sum = function (a, b) {
    10         return a + b
    11     }
    12     return factory;
    13 });
    14  
    15 //自定义computeServer服务
    16 app.service('computeServer', function (sumService) {
    17     this.sum = function (a, b) {
    18         return sumService.sum(a, b);
    19     };
    20 });
    21  
    22 //provider
    23 app.config(function ($provider) {
    24     $provider.provider('sumService', function () {
    25         this.$get = function () {
    26             var factory = {};
    27  
    28             factory.sum = function (a, b) {
    29                 return a + b;
    30             }
    31             return factory;
    32         };
    33     });
    34 });
    35  
    36 //constant 常量配置
    37 app.constant('save', 'false');
    38  
    39 //注入的value
    40 app.controller('ctrl', function ($scope, defaultval) {
    41     $scope.defaultval = defaultval;
    42 });

      2.9 route

     1 <body ng-app="myapp">
     2 <ul>
     3     <li><a href="#/">首页</a></li>
     4     <li><a href="#/product">产品</a></li>
     5     <li><a href="#/about">关于</a></li>
     6 </ul>
     7 <div ng-view></div>
     8 <script type="text/javascript">
     9     //添加route依赖
    10     angular.module('myapp', ['ngRoute'])
    11     ///$routeProvider.when(url, {
    12     //    template: string,   在 ng-view 中插入简单的 HTML 内容
    13     //    templateUrl: string, templateUrl 插入html模板文件
    14     //    controller: string, function 或 array,  function、string或数组类型,在当前模板上执行的controller函数,生成新的scope。
    15     //    controllerAs: string,   string类型,为controller指定别名。
    16     //redirectTo: string, function, 重定向地址
    17     //    resolve: object<key, function>  指定当前controller所依赖的其他模块
    18     //    });
    19     .config(['$routeProvider', function ($routeProvider) {  //$routeProvider 用来定义路由规则
    20         $routeProvider.when('/', { template: '这是首页' })  //$routeProvider.when 函数的第一个参数是 URL 或者 URL 正则规则,第二个参数为路由配置对象。
    21                       .when('/product', { template: '这是产品' })
    22                       .when('/about', { template: '这是关于我们' })
    23                       .otherwise({ redirectTo: '/' });
    24     }]);
    25 </script>
    26 </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就好了撒

      思想已经出来了,但雏形还未跟上,虽然很简单,但是我还是厚着脸皮写出来了

     1 <input type="text" id="inputid" name="name" value="none" />
     2 <script type="text/javascript">
     3     if (!window.localStorage) {
     4         document.write('<script src="xxx.js"><\/script>');
     5         //document.write('<script src="jquery-1.9.1.js"><\/script>');
     6         //(function (d) {
     7         //    d.query = function (selector) {
     8         //        return $(selector)[0];
     9         //    }
    10         //    Element.prototype.addEvent = function (types, fn) {
    11         //        return $(this).bind(types, fn);
    12         //    }
    13         //})(document);
    14     }
    15     window.onload = function () {
    16         var obj = document.query('#inputid');
    17         console.log(obj.value);
    18         obj.addEvent('change', function () {
    19             console.log(this.value);
    20         })
    21     };
    22 </script>
  • 相关阅读:
    js的浅拷贝与深拷贝
    用Nodejs连接MySQL(原文链接)
    HTML5交互性图表库
    GitHub Desktop离线安装包
    docker--Dockerfile--sonarqube
    docker --Nexus仓库
    docker --Dockerfile--一些语法
    zookeeper 四字命令
    docker --swarm创建一个集群
    docker --swarm启动2375端口监听
  • 原文地址:https://www.cnblogs.com/guofei0925/p/5481974.html
Copyright © 2020-2023  润新知