java script创建对象_javascript笔记:深入分析javascript里对象的创建

大家知道在java里面类可以具有静态属性和方法,无需实例化该类的对象,就可以访问这些属性和方法,但是javascript里面是不是只有通过对象初始化方式才会模拟出这样的特点了?其实不然,在编程语言里,类的方法和属性比较标准的叫法是:静态作用域定义的属性和方法任何时候都能从同一个位置访问。其实严格意义上说javascript是没有静态作用域,对象初始化可以产生这样的效果,但是它太不直观了,前面的博文里我讲到javascript语言设计时候省略的类这个定义,而是把类的定义赋予到了构造函数里面,那么我们可以这样思考,要想让javascript语言里有属于类的属性和方法,最佳的展现形式就是让构造函数本身具有属性和方法,大家看下面代码:

48304ba5e6f9fe08f3fa1abda7d326ab.png

function JsObj()

{

this.sayHello = function(){

console.log('Hello World!!!');

}

}

JsObj.whosay = function(){

console.log('sharpxiajun say Hello World!!!');

}

JsObj.whosay();

var obj = new JsObj();//sharpxiajun say Hello World!!!

obj.sayHello();//Hello World!!!

48304ba5e6f9fe08f3fa1abda7d326ab.png

这种写法体现类的静态属性和方法特点会更加清晰些,前不久有人告诉我javascript里面的面向对象的做法现在已经成为了一种实现面向对象的标准,有些新语言现在就借鉴javascript来设计自己的面向对象的机制,但是我另可不去相信这个说法,我还是愿意把java的方式作为面向对象的标准方式,而javascript只是用模拟方式来实现,如果真让我把javascript面向对象做为一个新标准来理解,惯性的思维可能很难让我对javascript面向对象的做法有更加清晰的认识。如果说上面代码所运用的原理无非是javascript里面函数就是对象,同样可以为其赋值或者授予方法。这个问题很简单,也很好理解,我这里拿出这段代码是想告诉大家,我在读一些经典框架源码时候,有些设计思想就是运用了这种写法,但是我却没有把他们当作静态变量来理解,导致有些代码没有读懂。

2.关于this指针的问题

这是javascript最最最重要的一个概念,它的用法是掌握javascript精髓的关键。我们先看看下面这句话很关键,它道出了this用法的精髓:

关键字this的用法:它用在对象的方法中,this总是指向调用该方法的对象。

这句话道出了this是存在于对象的方法,里面包含两个内容:对象和方法,方法属于对象,示例格式就是:

48304ba5e6f9fe08f3fa1abda7d326ab.png

var obj = {};//或者var obj = new Object();二者等价

obj.nation = 'China';

obj.say1 = function()

{

console.log(obj.nation);

}

obj.say2 = function()

{

console.log(this.nation);

}

obj.say1();//China

obj.say2();//China

48304ba5e6f9fe08f3fa1abda7d326ab.png

结果一样,这个正好体现了this使用在对象方法中,this总是指向调用该方法的对象。这是对this用法的标准定义,但是真的把这个概念理解透还真的下功夫,下面我抛开这个定义,列举我所知道的this的用法。

用法一:在函数中的使用

function JsObj()

{

this.nation = 'China';

console.log(this.nation);

}

JsObj();//China

那么这个this指向的是JsObj函数吗?回答是NO,this指向的是window,看下面代码:

48304ba5e6f9fe08f3fa1abda7d326ab.png

function JsObj()

{

this.nation = 'China';

console.log(this.nation);

}

JsObj();//China

console.log(nation);//China

console.log(window.nation);//China

console.log(this.nation);//China

48304ba5e6f9fe08f3fa1abda7d326ab.png

看到效果了吧,指向的是window,我想有些童鞋可能不太理解为什么,没关系,这个疑问会引出我下一个小节要讲的内容。

用法二:作为对象方法的调用

这个用法和我最开始讲this指针的用法类似,代码如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

function say()

{

console.log(this.nation);

}

var obj = {};

obj.nation = 'China';

obj.objSay = say;

obj.objSay();//China

48304ba5e6f9fe08f3fa1abda7d326ab.png

用法三:作为构造函数的调用

说道javascript构造函数,我就要反复再强调一个基础知识:在javascript里的构造函数包含了类的特性。下面看我写的代码:

function JsObj()

{

this.nation = 'China';

}

var obj = new JsObj();

console.log(obj.nation);//China

这个nation绝对不属于window了,大家信不信了?我们可以测试一下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

var nation = 'USA';

function JsObj()

{

this.nation = 'China';

}

var obj = new JsObj();

console.log(obj.nation);//China

console.log(nation);//USA

48304ba5e6f9fe08f3fa1abda7d326ab.png

用法四:apply调用时候的this

apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。测试代码如下:

48304ba5e6f9fe08f3fa1abda7d326ab.png

var nation = 'USA';

function say()

{

console.log(this.nation);

}

var obj = {};

obj.nation = 'China';

obj.objSay = say;

obj.objSay.apply();//USA

obj.objSay.apply(obj);//China

48304ba5e6f9fe08f3fa1abda7d326ab.png

apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为USA,证明this指的是全局对象。apply传入obj对象,this就指向了对象obj了,运行的结果是China。

3.执行环境及作用域

我在上面总结javascript里this用法时候提出了一个问题,为什么this指向了window,解释这个问题就会牵涉出javascript里面有一个非常重要的概念执行环境及作用域。

首先说道的是执行环境,什么是执行环境呢?在javascript里面执行环境分为两类,一类是全局环境,一类是局部环境,整个页面里被共享的方法和属性就是在全局环境,相对于全局环境,函数{}号里的执行环境就是局部环境,执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为,每个执行环境都定义了一个与之相关的变量对象,环境中定义的所有变量和函数都保存在这个对象里,虽然我们自己编写的代码无法访问这个对象,但解析器在处理数据时候后台会使用到它。

全局执行环境另一种说法是最外围的一个执行环境,在web浏览器的范围中(actionscript也是施行了ECMAScript标准,它的全局范围就和javascript的全局范围不同),全局执行环境被认为是window对象,因此全局变量和函数都是作为window对象的方法和属性来创建的,全局执行环境知道应用程序退出比如关闭网页或浏览器才会被销毁。而局部环境则是以函数对象作为关联对象。

javascript语言规定了全局执行环境和局部执行环境的概念,这就产生了一个极其重要的应用:作用域链。当代码在一个环境里面被执行的时候会创建变量的对象构成的作用域链,它的用途是保证对执行环境有权访问所有变量和函数的有序访问。作用域链的前端始终是当前执行代码所在的环境的变量对象。如果这个环境是函数,则将其活动对象作为变量的对象,活动对象在最开始时只包含一个变量,就是arguments对象,arguments在全局环境中是不存在的,作用域链的下一个对象来自包含前一个对象的外部环境,而再下一个变量对象则来自下一个包含环境,如此类推,一直延续到全局环境,全局环境永远是作用域链最后一个对象。

呵呵,看这个解释是不是有点晕啊,我想换个角度思考可能好理解点,在javascript里,所有的属性和方法都是属于某一个对象的,其实在javascript里面,所有方法或属性的调用都是obj.method(),obj.name样式,如果程序代码里调用属性或方法时候找不到这个调用对象,javascript解析器就会往函数作用域的上层作用域里找,直到window全局环境,实在找不到的就默认授予给window对象。

好了,今天内容就写到这么多吧,真没想到javascript一个个看起来简单的对象创建能延伸出这么多知识,回味下这种点到面的研究方法还是蛮不错的,最近做java太多(我最近想开起一个新系列,我一直想做的系列android,不过有人跟我说一个人精力有限,我还是先把没写完的东西写完),写javascrip的激情有点不够了,真希望有一个全职做前端的环境,不过java也是很有趣的,最近和博友交流后我越加有动力把三套javaEE框架写完,给自己打打气,加油了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/289868.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java虚拟机学习-JVM调优总结-新一代的垃圾回收算法(11)

java虚拟机学习-深入理解JVM(1)java虚拟机学习-慢慢琢磨JVM(2)java虚拟机学习-慢慢琢磨JVM(2-1)ClassLoader的工作机制java虚拟机学习-JVM内存管理:深入Java内存区域与OOM(3)java虚拟机学习-JVM内存管理:深入垃圾收集器与内存分配策略(4)java虚拟机学习-…

一分钟了解Android横竖屏 mdpi hdpi xhdpi xxhdpi xxxhdpi

DPI:每英寸像素数 简单的屏幕分辨率计算方法: DisplayMetrics metrics this.getResources().getDisplayMetrics(); float density metrics.density; int dpi metrics.densityDpi; int heightPixels metrics.heightPixels; int widthPixels metrics.widthPixels…

Eclipse在ubuntu平台不显示顶部菜单栏

1、问题 ubuntu上的eclipse用着用着特么就不显示顶部状态栏了 2、解决办法 sudo /etc/profile export UBUNTU_MENUPROXY0 reboot

利用 .NET Core 中的数据保护组件实现限时 Token

前言在业务开发时,我们常常需要生成有过期时间的 Token 凭证。比如重置密码,即使被其他人获取到链接,超过指定时间也无法操作,以保证安全性:常用的实现方式,可以使用缓存或数据库存储 Token 的过期时间。今…

CityEngine Web Scene如何在IIS下部署

CityEngine2012新增了发布Web场景的功能,可以通过本地的Web Scene Viewer打开,也可以发布到ArcGIS Online云端进行共享。如下图: 注:3ws场景包制作方法:选中模型->File->Export->Export Models…->CityE…

瀑布流

<html><head><meta charset"utf-8"><title>瀑布流</title><style type"text/css">#main {position: relative;}.box {padding: 5px;float: left;}.pic {height: auto;padding: 5px;border: 1px solid gray;border-rad…

java简易日历程序报告_简单的日历小程序(java编写)

import java.util.Scanner;public class CalendarDemo{public static void main(String[] args) {int sum 0;Scanner in new Scanner(System.in);System.out.print("请输入年份&#xff1a;");int year in.nextInt();Scanner sc new Scanner(System.in);System.o…

动态规划之石子合并

1、问题 ( 1 )路边玩法 有 n 堆石子堆放在路边,现要将石子有序地合并成一堆,规定每次只能移动相邻的两堆石子合并,合并花费为新合成的一堆石子的数量。求将这 N 堆石子合并成一堆的总花费(最小或最大)。 2、分析 ( 1 )建立最优值递归式 设 Min [i][j] 代表从第 i 堆石子到第 …

《vSphere性能设计:性能密集场景下CPU、内存、存储及网络的最佳设计实践》一1.1.1 确定参数...

本节书摘来华章计算机《vSphere性能设计&#xff1a;性能密集场景下CPU、内存、存储及网络的最佳设计实践》一书中的第1章 &#xff0c;第1.1节&#xff0c;[美] 克里斯托弗库塞克&#xff08;Christopher Kusek&#xff09; 著 吕南德特施皮斯&#xff08;Rynardt Spies&…

CityEngine快捷键一览表

Alt+鼠标左键:旋转 Alt+鼠标中键:平移 Alt+鼠标右键:缩放 鼠标左键:选择

WPF 使用DrawingVisual绘制高性能曲线图

一、前言项目中涉及到了心率监测&#xff0c;而且数据量达到了百万级别&#xff0c;通过WPF实现大数据曲线图时&#xff0c;尝试过最基础的Canvas来实现&#xff0c;但是性能堪忧&#xff0c;而且全部画出来也不实际。同时也尝试过找第三方的开源库&#xff0c;但是因为曲线图涉…

java 代码通用结构_java spring代码通用结构-java

src.main.java.com.company.projectname| - aop&#xff1a;类组。Spring AOP的Aspect仓库&#xff0c;是AOP的相关内容。定义了AOP切面类与织入方法。涉及Aspect&#xff0c;Around&#xff0c;PointCut&#xff0c;validator&#xff0c;SuppressWarnings&#xff0c;Logable…

数据结构(Java)——迭代器和列表的实例

感谢Java软件结构与数据结构 John Lewis Joseph chase 著 金名译 0. 迭代器关键概念&#xff08;补充理解&#xff09; 【1】迭代器是一个对象&#xff0c;它提供了一种依次访问集合中每个元素的方式。 【2】经常把集合定义为Iterable的&#xff0c;说明需要时可以提供一个迭代…

Android studio编译出现Failed to finalize session : INSTALL_FAILED_INVALID_APK

1、问题 我把项目里面的部分java文件导成jar文件&#xff0c;然后复制这个项目然后用Androi studio打开&#xff0c;导入jar编译出现这个错误 Installation failed with message Failed to finalize session : INSTALL_FAILED_INVALID_APK: Split lib_slice_7_apk was define…

Linux的SWAP分区空间不够用的情况下,如何添加SWAP分区

通常情况下&#xff0c;SWAP空间应大于或等于物理内存的大小&#xff0c;最小不应小于64M&#xff0c;通常应是物理内存的2-2.5倍。但根据不同的应用&#xff0c;应有不同的配置。如果是小的桌面系统&#xff0c;则只需要较小的SWAP空间&#xff0c;而大的服务器系统则视情况不…

地理信息科学前沿-[热词]

1. LBS Location Based Service&#xff1a;基于位置的服务&#xff0c;它是通过电信移动运营商的无线电通讯网络&#xff08;如GSM网、CDMA网&#xff09;或外部定位方式(如GPS)获取移动终端用户的位置信息&#xff08;地理坐标&#xff0c;或大地坐标&#xff09;&#xff0c…

《vSphere性能设计:性能密集场景下CPU、内存、存储及网络的最佳设计实践》一1.2.2 内存...

本节书摘来华章计算机《vSphere性能设计&#xff1a;性能密集场景下CPU、内存、存储及网络的最佳设计实践》一书中的第1章 &#xff0c;第1.2.2节&#xff0c;[美] 克里斯托弗库塞克&#xff08;Christopher Kusek&#xff09; 著 吕南德特施皮斯&#xff08;Rynardt Spies&a…

如何检查服务已在依赖注入容器中注册

前言依赖关系注入(DI)&#xff0c;是一种在类及其依赖项之间实现控制反转(IoC)的技术。在ASP.NET Core中&#xff0c;依赖关系注入是“一等公民”&#xff0c;被大量使用。但是有时&#xff0c;我们仅仅只需要知道服务是否在依赖注入容器中已注册。比如&#xff0c;不注册使用分…

java多核的利用率_java利用FutureTask、ExecutorService 在多核时代充分利用CPU运算

java利用FutureTask、ExecutorService 在多核时代充分利用CPU运算FutureTask、ExecutorService 相关知识&#xff0c;请看java,API一个使用FutureTask简单的例子&#xff1a;package com.spell.threads;import java.util.concurrent.Callable;import java.util.concurrent.Exec…

iOS9 Storyboard unwind segue反回传递事件时机详细步骤

当返回上一个界面且需要上一个界面做某事时&#xff0c;用unwind segue实现起来比delegate简单许多&#xff0c;甚至有时不适合用delegate来实现&#xff0c;那么我们就用unwind segue吧&#xff0c;而且像1->2->3这样的跳转,3视图可以通过unwind segue方便的返回到1、2任…