灵活的Javascript
Javascript是一门弱内容语言,不需要声明变量的类型, 这一点与PHP的语法类似。弱类型语法虽然灵活,当时他的缺点也很明显,由于规范性不明确,所以不离开维护等。因此有了一些Javascript语法糖,比如:TypeScript、CoffeScript等。这些语法糖给JS添加了一些新特性以便于团队的开发,需要将这些语法糖转换为浏览器支持的原生JS。
1. 使用命名空间收编变量
通常,尽量少用全局变量,因为可能会与他人命名冲突,可以将你的方法封装在一个对象内部减少冲突
var $ = { addClass: function (ele, clsName) { }, removeClass: function (ele, clsName) { } }
2. 对象的多种写法
通常,可以通过Object构造函数实例化一个对象,或者直接将一个子面量对象赋值给一个变量。在这里 字面量对象 可以有多种写法:由{}包括的字面对象、函数以及数组:
//如下三种写法都是可以的 var obj = []; obj.addClass = function() { console.log(1) } obj.addClass(); //1 var obj = function() {}; obj.removeClass = function () { console.log(2) } obj.removeClass(); //2 var obj = {}; obj.swipe = function() { console.log(3); } obj.swipe();
3. 第一次复制对象
在面向对象编程中最重要的一个思想就是复用,别人能够使用你封装的方法、而且别人可以修改你给的方法,但是不会影响你写的原有对象。那么思路是返回一个新对象:
//每个新对象都是独立存在的,互不干扰 var factory = function () { return { addClass: function() {}, removeClass: function() {} } }
var obj = factory();
上面的这个方法通常被称为工厂方法。factory只是一个普通函数,它与obj对象里面的方法没有任何关系,这里也不设计到类的概念。
4. 第一次使用类
Javascript不支持类的相关的概念方法,但是可以模拟类的实现,先写一个php类
<?php class Person { private $_age; //私有属性(非公开属性) protected $money; //受保护属性 public $name //公开属性 //构造器 public function __construct() { $this->_age = 25; $this->money = 100; $this->name = 'arraybuffer'; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; //特权方法:可以访问私有属性 public function setAge($age) { $this->_age = $age; } public function getAge() { return $this->_age; } //静态公共方法:所有类的实例共享一个方法 public static function sleep() { return 'I am sleeping'; } } ?>
JS类模拟与其他语言有很大的区别
//定义方法, 这里暂不实现private protected var Person = function() { this.name = null; //每个实例都有自己的name属性 this.getName = function() { //每个实例都有自己的getName方法 return this.name; } this.setName = function(name) { this.name = name; } }
JS最大的一个特点就是原型链继承:类的实例会继承类的prototype对象,这个功能非常强大,它可以将类的公共方法封装到原型对象上,可以有效的节省开销:
//定义方法, 这里暂不实现private protected var Person = function() { this.name = null; //每个实例都有自己的name属性 } Person.prototype.getName = function() { return this.name; } Person.prototype.setName = function(name) { this.name =name; } var person = new Person(); person.setName('arraybuffer'); console.log(person.getName());
这里的原型方法的作用有点php中static属性的意思,但是却别却大:原型方法是继承另外一个对象的方法,static方法却属于类的一个成员。所以他们只是功能类似。
支持链式调用:
var Person = function() { this.name = null; //每个实例都有自己的name属性 } Person.prototype.getName = function() { return this.name; //这里就没法支持链式调用了 } Person.prototype.setName = function(name) { this.name =name; return this; //返回对象,支持链式调用 } var person = new Person(); var name = person.setName('arraybuffer').getName(); console.log(name);
永远都要记住:不管是方法还是变量(方法与变量本质都是一个变量)都属于特定的对象,所以获取某个变量的值实质是获取某个对象下的变量,调用方法是调用特定对象下的方法,这里的对象被称为执行环境,方法内的this是该对象(执行环境)的引用。
var sex = 'male'; // window.a = 'arraybuufer'(传说在顶层作用域定义的变量被赋值到window对象下是javascript设计的一个败笔) this.sex = 'female'; // this是window的引用 console.log(sex); //female //新语法(修正版) let age = 25; // let定义的变量不再属于window了 this.age = 30; console.log(age); //25
以上就是Javascript类的初见,接下来会利用Javascript的特性模拟类的其他特性