作用域与this
面向对象
一、单例模式
1.1 对象数据类型的作用:
把描述一个对象的属性和方法放在一个单独的空间,与其他的对象分割开,即时出现属性名相同的情况,也不会产生冲突
var name="xiao 1"
var age=12
var name="xiao 2"
var aeg=13
//单例模式
var person1={
name="xiao 1",
age=12
}
var person2={
name="xiao 2",
age=13
}
单例模式就好像上面对象数据类型一样,使用分组编写代码思想。在单例模式中person1叫命名空间,只是存放空间的一个名字而已。
1.2 模块化开发:
在项目中使用单例模式来开发一个大型项目,把当前的需求分成若干个功能模块,每个人负责一部分,同时开发,最后把所有人的代码整合在一起。
// 公共模块
var utils = {
select: function () {
}
}
// tab模块
var tabRender = {
change: function () {
utils.select() //公共模块方法调用
}
}
// search模块
var searchRender = {
change: function () {
this.clickEvent() //自己命名空间下方法调用,this可以避免修改名字的麻烦
},
clickEvent: function () {
}
}
缺点:单例模式手工生产输出单个个体,需要批量多个是就麻烦。
二、工厂模式
2.1 工厂模式:
用函数封装实现同一件事相同的代码,要实现该功能,只需要执行函数就可以了。
function creatTable(w,h) {
var obj = {};
obj.width = w;
obj.height = h;
obj.fn = function () {
console.log("the table width is "+this.width+" and height is "+this.height)
}
return obj;
}
var myTable=creatTable(200,100)
myTable.fn()
2.2 低耦合高内聚:
减少页面中的冗余代码,提高代码的重复利用率
三、一些概念
- 继承:子类继承父类的属性和方法
- 封装:把相同的代码放在一个函数里面,以后要实现该功能执行函数就可以了。
- 多态:当前方法的多种形态。后台语言中包括重载(传入的参数不一样,方法也不一样,js没有重载)和重写(子类重写父类的方法通过原型链)。
- 对象:js中万物皆是对象。一个泛指
- 类:对象的具体细分
- 实例:一个类别中具体的一个个体
- 举个例子 对象:大自然;类:动物、植物、人 实例:猫狗 你我他
+内置类:
Number,String,Boolean,Null,Undefined
Object、Array、RegExp、Date、Function...
四、构造函数模式
主要的目的创建一个自定义类,并创建这个类的实例。
构造函数和工厂模式区别
4.1 执行的时候
构造函数要在类(首字母一般大写,不是函数和方法)(所有的类都是函数数据类型)前加new,返回的是类的实例
var a=creatTable(10,10)
var b=new CreatTable(10,12)
4.2 代码执行
先创建一个私有的作用域,形参赋值,进行预解释,代码执行从上到下执行。
特别的地方,不用手动创建空的对象obj,浏览器会默认帮我们创建一个对象数据类型(这个对象是我们当前类的一个实例)(用this代表),代码执行,把属性名、属性值赋予当前的实例,最后浏览器返回当前的实例。
function CreatTable(w,h) {
// 创建myTable实例 也就是this
this.width = w; // 赋值 myTable.width
this.height = h;
this.fn = function () {
console.log("the table width is "+this.width+" and height is "+this.height)
}
// 返回实例
}
var myTable=new CreatTable(200,100)
myTable.fn()
知识点:
1、js所有的类都是函数数据类型、所有的实例都是对象数据类型
2、类中this是类的一个实例
3、this.xxx=xxx都是私有属性,不同实例私有属性不相等
4.3 构造函数扩展
1、构造函数中new fn() 执行,如果没有传递参数,后面的括号可以省略new Fn。
2、this在类中出现指的是当前类的一个实例,在一个属性值是方法时,要看执行的时候前面有".",有就是点前面的,没有则是window
function Fn() {
this.a=50;
this.getA=function () {
console.log(this.a);
}
}
var F1=new Fn; // 类后面可以不加括号
F1.getA() //50 this-->F1
var F2=F1.getA //F2 --> function(){console.log(this.a);}
F2() //undefined this-->window
3、在构造函数中,浏览器会默认的返回一个对象数据类型的值,如果我们手动的创建返回的值。返回的是基本数据类型的值,创建的实例对象没有影响。返回的是引用数据类型的值,当前的实例会被返回值替换。
function Fn() {
this.x=1;
this.getX=function() {
console.log(this.x);
}
return {x:233} //基本数据类型没有影响
}
var f1=new Fn;
console.log(f1) //{x: 233}
4.4 检测类型
- 检测某一个实例是否属于这个类 instanceof
console.log(f1 instanceof Fn) true - 检测属性属于对象 in
console.log(x in f1) true - 是否是私有属性 hasOwnProperty
console.log(f1.hasOwnProperty("grtX")) true - 是否是公有属性
function hasPunProperty(obj,attr) {
retrun (attr in obj) && !obj.hasOwnProperty(attr);
}
console.log(hasPUnProperty(f1,"getX")) //flase
五、原型链模式
5.1 概述
构造函数模式有类和实例的概念,把两者区分开,那如何识别每一个类,就需要原型链模式。
把实例上公有的属性和方法放到类的原型上(xxxx.prototype)
function CreatTable(w, h) {
this.width = w;
this.height = h;
}
CreatTable.prototype.fn = function () {
console.log("the table width is " + this.width + " and height is " + this.height)
}
- 1、每一个函数数据类型(类)都有一个天生自带的属性(prototype),属性值是对象数据类型。
- 2、在prototype上浏览器天生给他加上一个constructor属性,属性值是当前函数(类)本身。
- 3、每一个对象数据类型(实例,对象,prototype)天生自带一个属性_proto_,属性值是当前实例所属类的原型(prototype)
5.2 原型链
一个实例的方法在运行的时候,如果这个方法是自己私有的,那么就直接用,如果不是私有的,那么通过__proto__去所属类的原型上去查找,如果还没有就通过原型的__proto__一直查到基类的Object.如果还没有报错,如果有就直接用了。我们把这种通过__proto__查找的机制叫做原型链.
5.3 批量设置原型上的公有属性和方法
1、起别名
function Fn() {
this.x = 100
}
var pro = Fn.prototype;
pro.getX = function () { }
pro.getY = function () { }
2、重构原型上的对象
重新开辟一个堆内存,存储自定义公有的属性和方法,原来浏览器开辟的堆内存会给替换掉(没有constructor指向不是创建实例的类而是向上查找的Object,为了保持一致可以手动增加constructor的指向)浏览器在空闲的时候会销毁回收内存。
function Fn() {
this.x = 100
}
Fn.prototype={
constructor: Fn,
getX: function () { },
getY: function () { }
}
用上面的方法给内置的类增加公有的方法,会把原来的属性和方法替换,浏览器会屏蔽这种方法。
但是我们可以一个个去修改内置的方法,重复修改没有则增加(用特殊的命名标记自己的方法)
Array.prototype = {
constructor: Array,
unique: function() {}
};
console.dir(Array.prototype);
////
Array.prototype.sort1 = function () {
console.log("ok");//this->ary 我们当前要操作的这个数组
};
var ary = [1, 2, 2, 1, 2, 3, 4, 2, 1, 3];
var res=ary.sort1(); //把sort1 改成sort 就是修该内置的sort
console.log(ary);
console.log(res);
5.4 原型,模式中this指向问题。
数组去重
Array.prototype.unique = function () {
var obj = {}
for (var i = 0; i < this.length; i++) {
var cur = this[i]
if (obj.cur === cur) {
this[i] = this[this.length - 1]
this.length--
i--
continue
}
obj.cur = cur
}
obj = null
return this
}
ary = [2, 12, 121, 12, 1, 2, 2, 1, 3, 41, 1]
ary.unique()
链式写法:执行完成数组的一个方法可以紧接着执行下一个方法
//数组从小到大,再倒序排列,去除最后的一个数,返回去除的数,原数组改变
Array.sort(function (a, b) {return a-b }).reverse().pop()
5.5 可枚举和不可枚举
Object.prototype.lol=function () { }
var obj={name:"小a",age=12}
for(var key in obj){
//for in默认的情况下只会遍历到实例的私有属性和我们在实例所属类的原型上增加的方法属性。
if(obj.propertyIsEnumerable(key)){
//原型上的方法和属性都是不可枚举的不管是内置还是增加的
console.log(key)
}
if(obj.hasOwnPerporty(key)) {
//另一种方法,只枚举公有的方法
console.log(key)
}
}
5.6 原型继承
子类和父类通过原型链有了关联,也是通过查找原型链来实现,
function A() {
this.x = 100
}
A.prototype.getX = function () { }
function B() {
this.y = 200
}
//让B继承A的方法和私有属性
B.prototype = new A;
//父类中公有和私有都会变成子类原型上的公有的属性和方法
作用域与this的更多相关文章
- Javascript 的执行环境(execution context)和作用域(scope)及垃圾回收
执行环境有全局执行环境和函数执行环境之分,每次进入一个新执行环境,都会创建一个搜索变量和函数的作用域链.函数的局部环境不仅有权访问函数作用于中的变量,而且可以访问其外部环境,直到全局环境.全局执行环境 ...
- JS核心系列:浅谈函数的作用域
一.作用域(scope) 所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的. function scope(){ var foo = "global&quo ...
- JavaScript模仿块级作用域
avaScript 没有块级作用域的概念.这意味着在块语句中定义的变量,实际上是在包含函数中而非语句中创建的,来看下面的例子: function outputNumbers(count){ for ( ...
- Spring中Bean的作用域、生命周期
Bean的作用域.生命周期 Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).protot ...
- js学习之变量、作用域和内存问题
js学习之变量.作用域和内存问题 标签(空格分隔): javascript 变量 1.基本类型和引用类型: 基本类型值:Undefined, Null, Boolean, Number, String ...
- ES6(块级作用域)
我们都知道在javascript里是没有块级作用域的,而ES6添加了块级作用域,块级作用域能带来什么好处呢?为什么会添加这个功能呢?那就得了解ES5没有块级作用域时出现了哪些问题. ES5在没有块级作 ...
- JavaScript基础学习-函数及作用域
函数和作用域是JavaScript的重要组成部分,我们在使用JavaScript编写程序的过程中经常要用到这两部分内容,作为初学者,我经常有困惑,借助写此博文来巩固下之前学习的内容. (一)JavaS ...
- 深入理解javascript函数定义与函数作用域
最近在学习javascript的函数,函数是javascript的一等对象,想要学好javascript,就必须深刻理解函数.本人把思路整理成文章,一是为了加深自己函数的理解,二是给读者提供学习的途径 ...
- JavaScript作用域
JavaScript作用域 JavaScript作用域一直是前端开发的难题,现在只要用五句话就可解决. 一.“JavaScript中无块级作用域” 在Java或C#中存在块级作用域,即:大括号也是一个 ...
- javascript中的变量作用域以及变量提升
在javascript中, 理解变量的作用域以及变量提升是非常有必要的.这个看起来是否很简单,但其实并不是你想的那样,还要一些重要的细节你需要理解. 变量作用域 “一个变量的作用域表示这个变量存在的上 ...
随机推荐
- 小白学习Spark系列六:Spark调参优化
前几节介绍了下常用的函数和常踩的坑以及如何打包程序,现在来说下如何调参优化.当我们开发完一个项目,测试完成后,就要提交到服务器上运行,但运行不稳定,老是抛出如下异常,这就很纳闷了呀,明明测试上没问题, ...
- RESTful API设计方法
1.如果已经开始逐步的接触到了RESTful API设计方法的朋友,首先要对HTTP/HTTPS有一个大致的了解,虽然本身和RESTful API没有什么关系.但是对于增加网站的安全性还是十分重要的, ...
- 数据结构(5) 第五天 快速排序、归并排序、堆排序、高级数据结构介绍:平衡二叉树、红黑树、B/B+树
01 上次课程回顾 希尔排序 又叫减少增量排序 increasement = increasement / 3 + 1 02 快速排序思想 思想: 分治法 + 挖坑填数 分治法: 大问题分解成各个小问 ...
- Codeforces 789A Anastasia and pebbles( 水 )
链接:传送门 题意:这个人每次都去公园捡石子,她有两个口袋,每个口袋最多装 k 个石子,公园有 n 种石子,每种石子 w[i] 个,询问最少几天能将石子全部捡完 思路:排个序,尽量每天都多装,如果 k ...
- NOIP2016 DAY2 T1 组合数问题
题目描述 组合数表示的是从n个物品中选出m个物品的方案数.举个例子,从(1,2,3) 三个物品中选择两个物品可以有(1,2),(1,3),(2,3)这三种选择方法.根据组合数的定 义,我们可以给出计算 ...
- bzoj 2834: 回家的路
题目 F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser DCOI Logout 捐赠本站 Notice:1 ...
- 页面与后台传递中文乱码问题(java乱码)
1.前台中文传递到后台乱码. 前台不须要处理, 系统一般都会默认把中文转化为ISO-8859-1类型. 仅仅需在后台接受数据是处理 Str为前台传过来的中文字符串: String inputer = ...
- 验证DG最大性能模式下使用ARCH/LGWR及STANDBY LOG的不同情况
总结: --两台单实例数据库做DG,数据库版本号10.2.0.1.0 1.主库配置为:arch async,备库无STANDBY LOG. 日志中会有:RFS[4]: No standby redo ...
- JavaScript——BOM(浏览器对象模型),时间间隔和暂停
BOM(浏览器对象模型):能够对浏览器的窗体进行訪问和操作 1.主要的BOM体系: window------------document-------------------------------- ...
- bzoj5288: [Hnoi2018]游戏
我还是太年轻了... 考场上就是直接枚举预处理当前位置左右延伸到的最远距离,好像是水了20.. 然后噶爷爷居然随机一下就AC了????mengbier #include<cstdio> # ...