如何prepareubuntu 查看发行版本本SystemJS和咕嘟咕嘟

译者注:(第一次翻译文章,翻译的不好请大家帮忙指出,希望看这篇文章的同学都有收获,非常感谢。)
什么是 jspm 和 systemjs?
过去的几年,js 项目越来越受欢迎,js 变成了开发web应用程序和混合移动应用的权威语言,js 项目变得越来越复杂,开发人员对于js有了新的需求,其中之一就是模块化。
据我所见,有2个方面的模块必须实现:
开发者自己写的模块
作为依赖关系的外部模块
和 ,这是向前的一大步,这意味着如果你今天想使用模块,你需要使用模块打包()。而且我们没有一个包管理器允许我们下载一个包,并将其引入进我们的应用程序中,包管理工具(如 bower 和 npm )帮助我们下载前端依赖且无需访问该项目的网站。在这篇文章中,我们将看到
是如何来解决这些问题。
的软件包管理器(又名jspm)是一个软件包管理工具,工作在systemjs通用模块加载器之上。它不是一个完全新的包管理工具,而是基于已经存在的包资源进行的,它与GitHub和NPM协同工作。因为大多数的 bower 安装包 基于GitHub,我们可以很好的使用jspm安装这些软件包。它有一个
,列出了最常用的前端模块,使用户方便安装。像NPM,它可以区分安装包是在开发环境或者生产环境。
systemjs是模块加载器,可以导入任何流行格式的模块(CommonJS、UMD、AMD、ES6)。它是工作在
之上,它能够很好的处理和检测所使用的格式。 systemjs 也能使用插件转换es6( 用
或者 )或者转换TypeScript 和 CoffeeScript代码。你只需要在导入你的模块之前使用 System.config({ … }) 进行系统配置。
jspm使用systemjs管理包及其依赖项,这样我们就不用担心包不按正确的顺序加载。现在我们知道jspm和systemjs 是什么了,下面让我们来看看如何使用它们。
安装我们的环境
如果你还没有准备好,你需要确保安装了 。一个特别简单的方法就是使用版本管理器(如NVM)它会有详细的。一旦你用node启动和运行,您可以运行以下命令全局安装jspm:
npm install -g jspm
安装好nodejs环境后就可以使用 。让我们执行以下命令建立一个项目:
mkdir new-project
cd new-project
npm init -y
npm install jspm --save-dev
将创建一个目录名为new-project的项目,使用npm初始化项目并局部安装jspm。这是开发项目,因为它锁定了一个项目,确保全局jspm升级不会改变应用程序的行为。这种方法的另一个好处是,如果你的项目是通过持续集成构建部署,您可以使用局部jspm包配置来取代没有全局安装jspm。
你可以使用jspm -v
确认本地版本。
Running against local jspm install.
在一个项目中使用jspm,运行以下命令:
之后将提示您进行一系列设置,按回车键接受默认值或键入一个不同的值来更改它们。下面的截图显示jspm init命令在默认设置下执行的例子:
目录结构和配置
它将在项目的根目录下创建创建一个名为config.js的文件以及一个名为jspm_packages的文件夹。如果你进入jspm_packages 文件夹内,你会看到:
一个github的子目录
一个 npm 的子目录
systemjs模块加载器的主要文件
jspm创建github 和npm目录的原因是它需要一份注册表来符合NPM或GitHub上包重命名的要求。此外,github目录包含一个systemjs插件去从GitHub和npm目录加载一份包含babel相关包的JSON文件来转换ES6代码。
这个config.js文件主要是systemjs的配置。如果你打开它,你会看到它的配置选项设置为不同来源包的路径,对于babel相关包的来源更容易区分。这个文件会自动更新当新的包使用jspm安装时。
该命令也更新了package.json文件并且为jspm添加一块区域。使用init 命令安装Babel相关包并添加devDependencies到项目里。
&devDependencies&: {
&babel&: &npm:babel-core@^5.8.24&,
&babel-runtime&: &npm:babel-runtime@^5.8.24&,
&core-js&: &npm:core-js@^1.1.4&
任何新的软件包的安装使用jspm命令使用或者不使用–save选项将被添加到dependencies部分,所以它就变成了一个生产环境依赖。安装使用–devDependencies选项使依赖保存到devdependencies区域。最后,jspm添加一个入口到映射到config. js文件中每个使用jspm命令安装的包。映射的名称可用于加载任何在你的项目中的文件。任何依赖的包都可以很好的添加映射。以下config.JS文件的代码片段展示了jQuery和jQuery UI包的映射以及如何依赖的定义:
&npm:jquery@2.2.0&,
&jquery-ui&:
&github:components/jqueryui@1.11.4&,
&github:components/jqueryui@1.11.4&:
&jquery&: &npm:jquery@2.2.0&
当你安装一个模块时,你也可以自动生成这些映射:
jspm install jq=jquery
这将允许你在其他地方写下你的应用程序:
var $ = require('jq');
jspm 和 SystemJS 的行为
为了结合这篇文章,我做了一个简单的维基百科搜索样本。它使用jspm init 命令来默认进行安装然后使用Babel转换ES6代码。它还使用jspm安装jQuery和Bootstrap。bootstrap依赖于jQuery,jspm在config.js中创建映射在加载bootstrap之前加载jQuery:
&github:twbs/bootstrap@3.3.6&:
&jquery&: &github:components/jquery@2.2.0&
正如仓库建议的,它查询了维基百科搜索的搜索接口,并显示了在视图中所接收的数据。它使用jQuery的的API$.ajax(),展示了结果页面上的一个链接去显示这篇文章的的弹出层。样本在scripts文件夹下有三个文件:
search.js:本文件采用的是AMD风格的模块。它加载jQuery作为依赖并用Ajax搜索来维基百科。该模块返回一个函数,该函数可以调用任何其他的模块并传入一个参数。
summaryModal.js:本文件使用ES6风格的模块。它加载Bootstrap的库。然后导出函数接受一块溢出的HTML和未溢出的HTML文本在弹出式窗口显示之前。
display.js:本文件使用CommonJS风格的模块。它加载jQuery和上述文件作为依赖。它要求被search.js得到结果,然后把这个数据渲染进HTML表格的UI中。此外,利用暴露的summaryModal.js显示一个模态框的链接按钮。
正如已经提到的,SystemJS 了解所有的模块系统。我们可以使用systemjs加载所有的上述三种类型的文件。
为了使这些脚本的运行,我们需要加载system.js和config. js在HTML页面。之后我们将使用systemjs加载display.js模块。根据仓库中这个文件的来源可以加载所有依赖的库,我们不需要加载任何其他文件。
System.import(&scripts/display.js&);
然而,转换代码有性能方面的问题且不应该被使用在生产中的应用中。别忘了,jspm是模块捆绑,所以让我们把它捆绑。
我们可以使用下面的命令为整个应用程序创建一个包:
`jspm bundle scripts/display.js build.js `
该命令做了以下行为:
将所有文件的依赖合成一个名为build.js的文件
转换的模块文件使用了systemjs模块加载方式
创建在调试期间加载的源映射文件
现在我们需要在index.html文件中加载build.js 文件。这里是更新的引用集:
System.import(&scripts/display.js&);
请注意,我们没有删除import声明语句加载的模块display.js。这句声明没有加载源文件了,取而代之的是加载一个systemjs创建的已经可用的build.js文件。你可以跟随项目的README文件去运行它。您可以在开发工具中浏览单个文件中的代码,并通过它们进行调试。
jspm和systemjs组合提供了一个安装和加载依赖的统一方式。这个工具不仅使管理依赖模块更简单,而且也让我们在现在的浏览器中可以使用未来的模块系统。我已经证明了,jspm易于安装和使用,这两个原因使其人气高涨。你的项目使用了jspm么?为什么?为什么不呢?在下面的评论中让我知道吧。
技术大牛书单Android playing resource files from internal storage causes MediaPlayer.prepare to give IOException - Stack Overflow
Join the Stack Overflow Community
Stack Overflow is a community of 7.0 million programmers, just like you, helping each other.
J it only takes a minute:
My app plays audio resource files from the internal directory designated for my app (/data/data/com...). It seems to download the files to that location okay, setDataSource(String path) doesn't throw any exceptions, but MediaPlayer.prepare() throws IOException.The same code works on the SD card. Why is this happening?
Let's ass it's simpler than my code and it throws the same exception:
package com.app.MediaPlayerT
public class MediaTest extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DownloadFiles();
MusicPlay();
public void DownloadFiles() {
//Downloads Files
public void MusicPlay()
mp.setDataSource("/data/data/com.app.pronounce/winds.mp3");
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
} catch (IllegalStateException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
mp.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
mp.setLooping(true);
mp.start();
As for the stack trace:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
"main" prio=5 tid=1 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x self=0xce48
| sysTid=338 nice=0 sched=0/0 cgrp=bg_non_interactive handle=-
| schedstat=(
at android.os.BinderProxy.transact(Native Method)
at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:2547)
at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:76)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:854)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:851)
at dalvik.system.NativeStart.main(Native Method)
"Binder Thread #2" prio=5 tid=8 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x40512b30 self=0x156e90
| sysTid=346 nice=0 sched=0/0 cgrp=default handle=1570912
| schedstat=( 487 3 )
at dalvik.system.NativeStart.run(Native Method)
"Binder Thread #1" prio=5 tid=7 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x40512a68 self=0x17f578
| sysTid=345 nice=0 sched=0/0 cgrp=bg_non_interactive handle=604904
| schedstat=( 72136 3 )
at dalvik.system.NativeStart.run(Native Method)
"Compiler" daemon prio=5 tid=6 VMWAIT
| group="system" sCount=1 dsCount=0 obj=0x4050eba8 self=0x938c8
| sysTid=344 nice=0 sched=0/0 cgrp=bg_non_interactive handle=1099136
| schedstat=( 79300 5 )
at dalvik.system.NativeStart.run(Native Method)
"JDWP" daemon prio=5 tid=5 VMWAIT
| group="system" sCount=1 dsCount=0 obj=0x4050eaf8 self=0x10c3c0
| sysTid=343 nice=0 sched=0/0 cgrp=bg_non_interactive handle=1098624
| schedstat=( 40040 20 )
at dalvik.system.NativeStart.run(Native Method)
"Signal Catcher" daemon prio=5 tid=4 RUNNABLE
| group="system" sCount=0 dsCount=0 obj=0x4050ea38 self=0x93570
| sysTid=342 nice=0 sched=0/0 cgrp=bg_non_interactive handle=588000
| schedstat=( 7632 7 )
at dalvik.system.NativeStart.run(Native Method)
"GC" daemon prio=5 tid=3 VMWAIT
| group="system" sCount=1 dsCount=0 obj=0x self=0x8f720
| sysTid=341 nice=0 sched=0/0 cgrp=bg_non_interactive handle=1099336
| schedstat=( 969 3 )
at dalvik.system.NativeStart.run(Native Method)
"HeapWorker" daemon prio=5 tid=2 VMWAIT
| group="system" sCount=1 dsCount=0 obj=0x self=0x10c740
| sysTid=340 nice=0 sched=0/0 cgrp=bg_non_interactive handle=1357728
| schedstat=(
at dalvik.system.NativeStart.run(Native Method)
MediaPlayer requires that the file being played has world-readable permissions. You can view the permissions of the file with the following command in adb shell:
ls -al /data/data/com.mypackage/myfile
You will probably see "-rw------", which means that only the owner (your app, not MediaPlayer) has read/write permissions.
Note: Your phone must be rooted in order to use the ls command without specifying the file (in the internal memory).
If your phone is rooted, you can add world-read permissions in adb shell with the following command:
chmod o+r /data/data/com.mypackage/myfile
If you need to modify these permissions programmatically (requires rooted phone!), you can use the following command in your app code:
Runtime.getRuntime().exec("chmod o+r /data/data/com.mypackage/myfile");
Runtime.getRuntime().exec("chmod 777 /data/data/com.mypackage/myfile");
Which is basically a linux command. See
for more on chmod.
EDIT: Found another simple approach
(useful for those without rooted phones). Since the application owns the file, it can create a file descriptor and pass that to mediaPlayer.setDataSource():
FileInputStream fileInputStream = new FileInputStream("/data/data/com.mypackage/myfile");
mediaPlayer.setDataSource(fileInputStream.getFD());
This approach avoids the permission issue completely.
29.1k1396127
I know this question is older than dirt, but it helped me flush out my issue. The following works fine:
FileOutputStream outStream= openFileOutput("movie.mp4", MODE_WORLD_READABLE);
The world readable flag is the important part here.
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
rev .25749
Stack Overflow works best with JavaScript enabledtypescript - How to prepare release version with SystemJS and Gulp? - Stack Overflow
Join the Stack Overflow Community
Stack Overflow is a community of 7.0 million programmers, just like you, helping each other.
J it only takes a minute:
I use SystemJS in my Angular2 project. I use tsconfig file for TypeScript. I want to use gulp to concat and minify my code for production version. I am having an issues with concating the code: each time I try to concat files I get either 'angular' not defined or 'system' not defined. I tried to modify the order that I try to load my files from node modules, however I did not succeeded.
I was wondering if any of you had this issues, and found an answer to it?
Here is my gulp file:
var gulp = require('gulp'),
var paths = {
dist: 'dist',
'node_modules/systemjs/dist/system.src.js',
'node_modules/angular2/bundles/angular2.dev.js',
'node_modules/angular2/bundles/angular2-polyfills.js',
'node_modules/angular2/bundles/router.dev.js'
templates: [
'app/**/*.html',
'!node_modules/*.html'
scripts: [
'app/**/*.ts',
'app/config.ts',
'app/app.ts'
var tsProject = ts.createProject('tsconfig.json', {
out: 'Whatever.js'
gulp.task('dev:build:templates', function () {
return gulp.src(paths.app.templates)
.pipe(ngHtml2Js({
moduleName: 'Whatever',
declareModule: false
.pipe(concat("Whatever.tpls.min.js"))
.pipe(gulp.dest(paths.dist));
gulp.task('prod:build:templates', function () {
return gulp.src(paths.app.templates)
.pipe(minifyHtml({
empty: true,
spare: true,
quotes: true
.pipe(ngHtml2Js({
moduleName: 'whatever',
declareModule: false
.pipe(concat(paths.appName + ".tpls.min.js"))
.pipe(uglify())
.pipe(gulp.dest(paths.dist));
gulp.task('dev:build:scripts', function () {
var tsResult = tsProject.src()
.pipe(sourcemaps.init())
.pipe(ts(tsProject));
return tsResult.js
.pipe(sourcemaps.write({
sourceRoot: '/app'
.pipe(concat('whatever.js'))
.pipe(gulp.dest(paths.dist));
gulp.task('dev:build:styles', function () {
return gulp.src(paths.app.styles)
.pipe(sass())
.pipe(gulp.dest(paths.dist + '/css'));
gulp.task('dev:build:vendor', function () {
return gulp.src(paths.vendor.js)
.pipe(concat('vendor.min.js'))
.pipe(gulp.dest(paths.dist))
gulp.task('dev:build', [
'dev:build:vendor',
'dev:build:templates',
'dev:build:scripts',
'dev:build:styles',
], function () {
This is how I load my files:
&script src="vendor.min.js"&&/script&
&script src="Whatever.js"&&/script&
&script src="Whatever.tpls.min.js"&&/script&
And here are the erors that I am getting:
Uncaught TypeError: Unexpected anonymous System.register call.(anonymous function) @ vendor.min.js:2680load.metadata.format @ vendor.min.js:3220oldModule @ vendor.min.js:3749(anonymous function) @ vendor.min.js:2411SystemJSLoader.register @ vendor.min.js:2636(anonymous function) @ Whatever.js:2
Whatever.tpls.min.js:1 Uncaught ReferenceError: angular is not defined
9,53163865
3,77752465
You will get " Unexpected anonymous System.register call" because the references are not being loaded in the correct order. I use JSPM to properly build my angular app for production.
There are 4 parts to the process.
Compile your typescript files
var ts = require("gulp-typescript");
var tsProject = ts.createProject("./App/tsconfig.json");
gulp.task("compile:ts", function () {
var tsResult = tsProject.src()
.pipe(ts(tsProject));
tsResult.js.pipe(gulp.dest("./wwwroot/app"));
Configure config.js (to tell JSPM how to bundle your app):
System.config({
baseURL: "/",
defaultJSExtensions: true,
"npm:*": "jspm_packages/npm/*",
"github:*": "jspm_packages/github/*",
"node_modules*": "node_modules/*"
'app': 'app',
'rxjs': 'node_modules/rxjs',
'@angular': 'node_modules/@angular'
packages: {
'app': { main: 'bootDesktop.js', defaultExtension: 'js' },
'rxjs': { defaultExtension: 'js' },
'@angular/common': { main: 'index.js', defaultExtension: 'js' },
'@angular/compiler': { main: 'index.js', defaultExtension: 'js' },
'@angular/core': { main: 'index.js', defaultExtension: 'js' },
'@angular/http': { main: 'index.js', defaultExtension: 'js' },
'@angular/platform-browser': { main: 'index.js', defaultExtension: 'js' },
'@angular/platform-browser-dynamic': { main: 'index.js', defaultExtension: 'js' },
'@angular/router': { main: 'index.js', defaultExtension: 'js' },
'@angular/router-deprecated': { main: 'index.js', defaultExtension: 'js' },
'@angular/testing': { main: 'index.js', defaultExtension: 'js' },
'@angular/upgrade': { main: 'index.js', defaultExtension: 'js' }
Use gulp-jspm-build to bundle up your app (I was previously using gulp-jspm but it was causing errors, so I switched to gulp-jspm-build):
var jspm = require('gulp-jspm-build');
gulp.task("jspm_bundle", function () {
return jspm({
bundleOptions: {
minify: true,
mangle: false
bundleSfx: true,
bundles: [
{ src: './wwwroot/app/appBoot.js', dst: 'boot.bundle.min.js' }
.pipe(gulp.dest('./wwwroot/js-temp'));
//this will create a file called boot.bundle.min.js
//note I have set jspm to create a self-executing bundle
//I put mangle to false because mangling was causing errors
Now concat all your already minified assets:
gulp.task("min:js", ["jspm_bundle"], function () {
//this only concats boot.bundle.min.js
//and dependencies.min.js which has already been minified such as es6-shim.js
var files = [
"./wwwroot/js-temp/dependencies.min.js",
"./wwwroot/js-temp/boot.bundle.min.js"
return gulp.src(files)
.pipe(concat("boot.bundle.min.js"))
.pipe(gulp.dest("./wwwroot/js"));
Finally, put one nice tidy script reference into your index.html:
&script src="~/js/boot.bundle.min.js"& &/script&
One of the nice features of this approach is that your bundled app will only contain the assets that are actually referenced in you import statements (jspm won't bundle it if you don't need it).
Revised config.js to conform to a Angular 2.0-rc.0 appp
tsconfig.json looks like this:
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"module": "commonjs",
"moduleResolution": "node",
"noImplicitAny": false,
"noEmitOnError": true,
"removeComments": false,
"sourceMap": true,
"declaration": false,
"noLib": false,
"target": "es5",
"outDir": "wwwroot/app/"
"exclude": [
"node_modules",
3,64322237
You can use
as easy as this
var path = require("path");
var Builder = require('systemjs-builder');
// optional constructor options
// sets the baseURL and loads the configuration file
var builder = new Builder('path/to/baseURL', 'path/to/system/config-file.js');
.bundle('local/module.js', 'outfile.js')
.then(function() {
console.log('Build complete');
.catch(function(err) {
console.log('Build error');
console.log(err);
you can look at the full setup in my
I think we found the root cause of this. Honestly, I have been there before so the way I trace this type of issue are
Check if angular & systemjs are loaded beforehand.
Check if they are really loaded. no 404 surprise. (It sounds stupid but shit happens)
If you bundle libraries as vender.js make sure they are bundle in correct sequence. Check the output file and see if they are concat as the way you expect.
16.8k84965
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
rev .25749
Stack Overflow works best with JavaScript enabledJavaScript(65)
在开始摆弄代码之前,应该搞清楚使用继承的目的和能带来什么好处。一般来说,在设计类的时候,我们希望能减少重复性的代码,并且尽量弱化类之间的耦合。而要做到这两者都兼顾是很难的,我们需要根据具体的条件和环境下决定我们应该采取什么方法。根据我们对面向对象语言中继承的了解,继承会带类直接的强耦合,但js由于其特有的灵活性,可以设计出强耦合和弱耦合,高效率和低效率的代码。而具体用什么,看情况。
下面提供js实现继承的三种方法:类式继承,原型继承,掺元类。这里先简述类式继承,后两种在往后的随便中简述,请多多关注、指导,谢谢。
类式继承。
js类式继承的实现依靠原型链来实现的。什么是原型链?js中对象有个属性prototy,这个属性返回对象类型的引用,用于提供对象的类的一组基本功能。
貌似对prototype有印象,对了,我们经常这样用代码。
var&Person
= function(){&&&
&&&&this.name
= &liyatang&;
Person.prototype
&&&&getName
: function(){
&&&&&&&&return&this.
我们把类的基本功能放在prototype属性里,表示Person这个对象的引用有XXX功能。
在理解原型后,需要理解下什么是原型链。在访问对象的某个成员(属性或方法)时,如果这个成员未见于当前对象,那么js会在prototype属性所指的那个对象中查找它,如果还没有找到,就继续到下一级的prototype所指的对象中查找,直至找到。如果没有找到就会返回undifined。
那么原型链给我们什么提示呢?很容易联想到,原型链意味着让一个类继承另一个类,只需将子类的prototype设置为指向父类的一个实例即可。这就把父类的成员绑定到子类上了,因为在子类上查找不到某个成员时会往父类中查找。(以上这两段用词不严谨,只在用通俗易懂的言语描述)
下面我们需要个Chinese类,需要继承Person类的name和getName成员。
var&Chinese
= function(name,
&&&&Person.call(this,name);
&&&&this.nation
Chinese.prototype
Chinese.prototype.getNation
= function(){
&&&&&&&&return&this.
继承关系就建立了,我们这样调用它
= new&Chinese(&liyatang&,&China&);
alert(c.getName());
于是类式继承就这样完成了。难道真的完成了嘛,用firebug在alert那里设断点,会发现原来的Person.prototype被修改了,添加了getNation方法。
这是因为在上面的代码Chinese.prototype = Person. 这是引用类型,修改Chinese同时也修改了Person。这本身就是不能容忍的,且使类之间形成强耦合性,这不是我们要的效果。
我们可以另起一个对象或实例化一个实例来弱化耦合性。
这两种方法有什么区别呢。在第二种中添加了一个空函数F,这样做可以避免创建父类的一个实例,因为有可能父类会比较庞大,而且父类的构造函数会有一些副作用,或者说会执行大量的计算任务。所以力荐第二种方法。
到此,完了嘛,还没有!在对象的属性prototype下面有个属性constructor,它保存了对构造特定对象实例的函数的引用。根据这个说法Chiese.prototype.constructor应该等于Chinese,实际上不是。
回忆之前在设置Chiese的原型链时,我们把Person.prototype 覆盖掉了Chiese.prototype。所以此时的Chiese.prototype.constructor是Person。我们还需要添加以下代码
if(Chinese.prototype.constructor
== Object.prototype.constructor){
&&&&Chinese.prototype.constructor
整理全部代码如下
var&Person
= function(name){
&&&&this.name
Person.prototype
&&&&getName
: function(){
&&&&&&&&return&this.
var&Chinese
= function(name,
&&&&Person.call(this,name);
&&&&this.nation
= function(){};
F.prototype
Chinese.prototype
if(Chinese.prototype.constructor
== Object.prototype.constructor){
&&&&Chinese.prototype.constructor
Chinese.prototype.getNation
= function(){
&&&&&&&&return&this.
= new&Chinese(&liyatang&,&China&);
alert(c.getName());
如果可以把继承的代码放在一个函数里,方便代码复用,最后整理代码如下
function&extend(subClass,superClass){
= function(){};
&&&&F.prototype
= superClass.
&&&&subClass.prototype
= new&F();
&&&&subClass.prototype.constructor
&&&&subClass.superclass
= superClass.
&&&&if(superClass.prototype.constructor
== Object.prototype.constructor){
&&&&&&&&superClass.prototype.constructor
var&Person
= function(name){
&&&&this.name
Person.prototype
&&&&getName
: function(){
&&&&&&&&return&this.
var&Chinese
= function(name,
&&&&Person.call(this,name);
&&&&this.nation
extend(Chinese,
Chinese.prototype.getNation
= function(){
&&&&&&&&return&this.
= new&Chinese(&liyatang&,&China&);
alert(c.getName());
发表后修改:
在一楼的评论下,我对那个extend函数又有新的看法。之前在讨论如何设置原型链时提出了两种方法
虽然第二种减少了调用父类的构造函数这条路,但在设计Chinese类时用了Person.call(this,name);这里也相当于调用了父类的构造函数。
然而用第一种方法的话可以减少在Chinese中再写Person.call(this,name);,这部分代码在子类中往往会遗忘。不妨把这种功能代码放在了extend里。就只写
Chinese.prototype = new Person();也达到同样的目的:耦合不强。
但遗忘的一点是,Chinese.prototype = new Person();这样写对嘛。答案是不对!很明显 new Person()需要传一个name参数的。我们不可能在extend函数里做这部分工作,只好在Chinese类里调用父类的构造函数了。这样也符合面向对象的思路。
所以,还是力荐用第二种方法。
第一次这样写有关技术类的文章,基本是按自己的思路铺展开来,难免会有一些没有考虑到的地方和解释的不清楚的地方,望留言反馈,谢谢。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:923046次
积分:16609
积分:16609
排名:第512名
原创:657篇
转载:659篇
评论:66条
(2)(3)(1)(2)(1)(1)(1)(1)(5)(3)(2)(3)(14)(2)(2)(2)(15)(2)(5)(15)(26)(18)(15)(55)(33)(35)(23)(33)(54)(100)(90)(96)(161)(96)(111)(95)(66)(117)(7)(1)(4)

我要回帖

更多关于 linux发行版本 的文章

 

随机推荐