诸葛亮《诫子书》

No comments September 1st, 2009

夫君子之行:静以修身,俭以养德。非淡泊无以明志,非宁静无以致远。夫学须静也,才须学也。非学无以广才,非志无以成学。淫慢则不能励精,险躁则不能治性。年与时驰,意与日去,遂成枯落,多不接世,悲守穷庐,将复何及!

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

尼尔森:网民使用社交网站时间同比增长82%

No comments March 10th, 2010


尼尔森市场调查公司公布的调查结果显示,去年12月全球网民平均在Facebook和Twitter等社交网站上耗时超过五个半小时,较2008年12月增长了82%,当月Facebook和Twitter用户在这些网站上逗留约三个小时。

尼尔森的数据显示,Facebook是去年12月最大的社交网站,用户总数达到了2.07亿人,占据全球社交网络用户的67%。

去年12月在所有网站和网络应用中,社交网站和博客是最受欢迎的,其次是网络游戏和即时信息。在各个国家中,美国网民登陆社交网站的热情最高,当月独立访问量达到了1.421亿人;排名前列的还有日本(4650万人)和巴西(3130万人)。

澳大利亚网民当月平均在社交网站上耗时近七个小时,排名全球首位。美国、英国和意大利网民则每月耗时约六个小时。

去年12月,美国网民平均在Facebook和Twitter上耗时超过六个小时。在Facebook上耗费的时间较上年同期增长了 200%,而在Twitter上耗费的时间同比增长了368%。在尼尔森调查中的五大社交网站中,Twitter继续保持着最快的增长速度,去年12月独立用户达到了1810万人,较2008年12月增长了579%。

附表:2009年12月各国网民使用社交网站情况

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

怎么确定这是一个创业的好机会?

No comments March 10th, 2010

1. 你的新产品,可以解决别人的问题、困扰、痛苦、不愉快吗?

当 iPhone 上市时,主打的并不是“触碰式萤幕手机”,而是“真正的随处上网”。因为 iPhone 之前的手机,按键都没有问题,所以触碰萤幕,并不能帮人解决任何问题。然而大家早就受够了那些“笨蛋手机”的内建浏览器,所以当 iPhone 打出 real internet 时,刚好正中下怀,因此马上获得市场热烈的反应。

2. 很多人有这样的问题吗?

决定了产品後,还必须了解市场的大小,这也往往是最难的确认的。不过,大部分时候,你可以找到“前一代”产品,或是英文市场的类似产品等等,来看出一些端倪。

3. 这些人有消费能力吗?可以立刻买单吗?

别忘了 Web 1.0 的教训,眼珠不等於营收,所以,潜在客户的口袋有没有麦克麦克,很重要。这点可以参考我之前对於繁体中文、简体中文、英文等各个市场,会员价值的分析。

4. 你有什么独特的经验和技能,可以把这个产品做得比别人好?

律师们都很聪明,但如果你的车坏掉了,大概不会找一个律师朋友帮你修理吧?但是,如果是一个爱重型机车成痴,每天在车库摸车的律师朋友,或许你会考虑吧?另外,网路是个很竞争的产业,随时都有许多团队在做类似的事情,你必须要知道自己有什麽优势,可以在这些人中胜出。

5. 你有什么特殊的资源,是别人没有的?

除了经验和技能外,或许你有一些特殊的管道,例如:有个有钱的亲戚、认识一个没事开什麽免费育成中心的怪人、这个怪人还传授你很多秘诀、最後他还投资你等等,这些可以帮助你赢过竞争对手的资源,也非常重要。

6. 你可以找到 2 个以上的合伙人加入你吗?

网路历史上成功的创业公司,都是有 2 个以上的核心成员的 — Google 有佩吉和布林,Yahoo 有杨志远和费罗,Facebook 虽然是沙克博比较有名,但其实也有 4 个主要创办人。合夥人有太多的好处,除了精神上的支持,常常也可以提供不同的观点,所以你需要其他人的加入,即使不是全职也没关系。

7. 他们的个性、经验、技能跟你互补吗?

这点大概不用解释,不过有一点很重要的,找合夥人的时候,EQ 非常的重要,创业过程就像云霄飞车,常常起起伏伏,最怕意气用事和没办法承受压力的夥伴,这些人不仅会害大家情绪低落,有时候还会让创业迷失了方向。

8. 他们的价值观跟你相近吗?

如果一个人想攻大众市场,一个人想攻金字塔尖端,那很难成事。一个人想要靠广告赚钱,一个人想要用 Freemium 模式,那也很难。所以尤其在商业模式上,价值观相近,相当重要。

9. 业界先进和相关的朋友们,觉得这是一个好机会吗?

跟合夥人一样,创业家也需要一些相关产业的先进和朋友,来给你关键的回馈。美国的创业团队,往往都会给自己找一个顾问群 (advisory board),给他们一点点公司的股票,然後不断的向他们请益。这点在台湾还不流行,我鼓励大家可以多多学习。

10. 有没有人觉得这是一个烂主意?

更重要的是,要了解为什麽他们觉得是个烂主意,然後要把这些建议,转化成方向的修正,让你的主意变得更完整、更实际。当然,如果他们只是出自於对新东西、新方法的不理解和害怕 (出版业 vs. 电子书),那反而是很好的肯定。

11. 这是一个你非常想要的产品吗?

创业的过程非常辛苦,在背後支撑你的,往往是你对这个产品的热情。而这股热情,也常常是让你更愿意花时间去研究,花精神去把产品做得比别人更好的动力。

12. 为什么相关的大公司短期内不会进入这个市场?

或许是成本,或许是市场规模,或许是速度,你必须要了解产业的大家伙们,为什麽短期内不会来跟你抢饭碗,让你可以有时间养足实力,跟他们一决胜负。

13. 你能找到几个潜在客户帮你测试吗?

这点常常是非常重要的,几个关键的测试用户,对产品的最後走向,有很大的影响。找到对的人,想办法让他们参与,就是成功的一半。

14. 这个产品只需要花一点点钱就可以开发出来?

这点在 Web 3.0 时代,其实已经非常明显。但是更重要的是,不要一口气就想做出 100 个功能,先从最重要的一个开始,先上线,再慢慢增加功能。

15. 产品上市后,公司的固定成本可以维持的很低?

如果你的服务每增加一个使用者,就必须要多买三台主机,那再好的产品,大概也很难获利。所以在财务上,如果边际成本是递减的,也就是随着使用者增加,每多一个人多出的成本会越来越少,那是最好的。

测验结果以上 15 个问题,如果有 12 题以上答是,那恭喜你,你手上的创业机会,相当不错。但更重要的是,所有不到 15 的人,都要努力的修正、改善,把你的创业主题,变成满分,那创业也就离成功不远了。

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Loss Aversion

No comments March 10th, 2010

多伦多大学和芝加哥大学的两个经济学家跑到中国的一个生产电子产品的工厂,拿中国工人做了一次实验。

在一周开始的时候,这个工厂的某些工人被告知,如果你们能完成本周的生产任务,将获得80元的奖金。而另一些工人则被告知,本周你们有80元奖金,但是如果不能完成生产任务,就会失去这笔奖金。

不都是完成任务多拿80块钱么?但是有区别。在第二组工人看来,80元钱已经是自己的了,关键词是“失去”。这里涉及到一个重要的心理学定律,叫做 loss aversion,损失规避。人,总是害怕失去胜过爱好得到。我曾经写过一篇《不买彩票买保险?》说的是类似的现象。实验结果果然不出所料,第二组工人完成任务的情况更好。我不知道这个实验在学术上有什么新意,也许工厂获得的教训应该是全面提高员工工资,然后一旦完不成任务就扣钱。

How We Decide 这本书就是神经科学家写的,此书中描写了一个类似的实验。实验人员递给受试者50美元(在美国做实验一出手就是50美元,去中国做一个星期才80人民币,这可能解释了为什么第一个实验要去中国做),受试者有两个选择。第一个选择是赌一把,赌局的概率是有40%的机会可以把50元都拿走,60%的机会一分都拿不到。另一个选择是不赌,直接拿其中20元走人。实验结果是大多数人选择直接拿20元走人,只有42%的人选择冒险。

与中国工人的实验类似,如果第二个选择换个说法:改成“直接损失30元”,则62%的人选择赌。典型的损失规避。

但这个实验的关键之处是当受试者权衡选择的时候,实验人员正在用核磁共振观察他们的大脑!他们发现,在跟第二组实验受试者说”损失”的时候,他们大脑中的一个特定区域,amygdala,兴奋了。这个区域的特点是一旦兴奋就会产生一种负面的感情。

负面感情比正面感情对人的影响大。正如这些损失规避实验所揭示的,人们对负面感情的重视程度总是超过正面感情。心理学对这个更一般的现象也有个名 词,叫 negativity bias,我不知道这个术语的标准翻译是什么,姑且称之为负面偏见。有些心理学家认为损失规避是负面偏见的一种,也有人认为二者不应混淆。我猜测,如果从脑成像角度去看,很可能二者就是一回事,都是大脑中某个区域兴奋而产生了负面的感情。

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

11 innovation lessons from creators of World of Warcraft

No comments October 29th, 2009

(This post consolidates lessons published in the O.C. Register and the “Inside Innovation” blog. For a link to more business lessons from World of Warcraft, see the April 17 post “A double serving of business lessons from World of Warcraft.)

Blizzard Entertainment, the envy of the computer game industry, has learned 11 lessons on innovation that can help almost any business.

Irvine-based Blizzard used these innovation methods not only to create the world’s most popular massively multi-player online game, World of Warcraft, but also to keep the game fresh and challenging for more than 10 million players.

Because many of those customers pay $15 a month to continue playing, Blizzard’s ongoing creative achievement is worth more than $1 billion a year in revenues, not counting the multi-millions it tallies from its other games, such as StarCraft, Diablo II and Warcraft III, plus trading cards, comic books, etc.

This combination of creativity and profitability is much of the reason for the upcoming merger of game company Activision with Blizzard’s parent company, Vivendi Games. The new company, to be called Activision Blizzard, will be valued at about $18.9 billion.

The following lineup of innovation lessons emerged from a video game conference, an interview, and several experts’ comments.

Blizzard executives discussed the company’s innovation processes during the D.I.C.E. video game conference last month in Las Vegas. Then, in early March, World of Warcraft lead producer J. Allen Brack explained his teams’ work methods during an interview at Blizzard’s new headquarters in Irvine. I also invited several business and innovation experts in Orange County to comment on how Blizzard works and how it and other creative enterprises such as the Walt Disney Co. innovate to keep their customers interested.

1. RELY ON CRITICS

Blizzard welcomes criticism – seeks it, in fact – both during game development and after the launch, when games need to be fine-tuned and freshened up.

In a process that is common for software companies, an alpha test provides crucial pre-release feedback from company employees. When the game software is ready, Blizzard moves to a beta test involving a limited number of outside players. Blizzard plans a beta test of its upcoming Wrath of the Lich King expansion pack for World of Warcraft, but hasn’t announced when it will begin.

In addition, tens of thousands of Blizzard subscribers sign in to the game’s Public Test Realm area to test and give advance feedback on patches, upgrades and revisions for the current version of World of Warcraft.

“Seeking out customers’ viewpoints and criticisms is an ideal way for businesses to align products and services to what their customers want,” said Ardelle St. George, intellectual property attorney and chairman of the Orange County Innovation group.

Innovation educator Marty Wartenberg of UCI Extension and the ZB Global Design Center in Carlsbad said, “It is very useful when developing your design and product to have third-party objective folks review and critique the design.”

“The idea is that colleagues will not be completely honest and critical with the participants present,” he said. “It would be much healthier if folks could take well-meaning and constructive criticism as a chance to improve the product or service. Unfortunately human nature tends to resist. This is a challenge to overcome in the business world.”

Mike Morhaime, Blizzard CEO and cofounder, said criticism is important, but it’s hard to take at first, as he recalled from tests of Blizzard’s early game The Lost Vikings.

“We thought the game was good enough, but Brian Fargo of Interplay took it home and played it, and had lots of feedback,” Morhaime said. Fargo wanted all the Viking characters to be redrawn so they wouldn’t look so similar, which the game team didn’t want to hear.

“It means he really cares,” Morhaime told them. “When I digested it, I thought, ‘Hey, these are good comments.’ ”

2. USE YOUR OWN PRODUCT

At Blizzard, that’s an easy demand, since the product is a game that’s fun to play. Game developers should find a new job if it they can’t enjoy playing it and, in the process, spot ways to make it better.

“We’re all fans. We all play,” said Brack, who averages 15 hours playing World of Warcraft each week.

At home after quitting time, he often plays his high-level World of Warcraft character for four hours, taking notes on what works and what doesn’t, he said. The next day at work, he meets with team members to discuss the problems he found.

In some industries, taking on the role of the customer “is referred to as ‘eating your own dog food,’ ” Wartenberg said, “actually using your product before subjecting the consumers to what may be an ill-conceived and poorly designed product.”

“In the theme park business (Disney and others), they have a phase in their development life cycle called ‘Family and Friends.’ This occurs right after the state regulatory body approves the event or attraction and before the general public gets to ride your new attraction. This gives the design folks the chance to see how normal or non-involved people react,” he said, “a final chance to make changes prior to opening it up.”

3. MAKE CONTINUAL IMPROVEMENTS

Criticism of the Vikings game “was our first painful iterative process,” Morhaime said, “and it’s happened with every game at Blizzard.”

Multi-disciplinary “strike teams” repeatedly critique the latest version of each game in progress.

“We do it every couple of weeks,” said Rob Pardo, senior vice president of game design, in the panel discussion with Frank Pearce, executive vice president of product development.

“It’s possible to go too far,” Pardo said, “and that’s what Frank and I are supposed to keep charge of. We’re trying to make great entertainment projects, not perfect ones. If we wanted to make perfect ones, we’d never be finished.”

St. George added, “Making continual improvements is a must for all types of goods and services. A competitive advantage can be attained from attention to improvement, innovation and detail.”

“In many industries, near perfection is the goal,” Wartenberg said, “whether we call it Zero Defects or Six Sigma (one error in 3.14 million) this is very true of the biotech/pharma community as well as those in aerospace, where human life is at risk. The emergence of process improvement methodologies in many of our local companies, (Lean, Six Sigma, Theory of Constraints, etc) attest to the fact that management recognizes that reducing errors, improving reliability and eliminating scrap are worthwhile and quickly drop to the bottom line.”

4. GO BACK TO THE DRAWING BOARD

Blizzard Entertainment will throw out unsuccessful work rather than try to salvage a fatally flawed plan.

“We come up with a lot of great ideas, we talk about them, we implement a lot of art and game play, and then we go ‘… that kind of sucks,’ said Pardo. “So do we do a re-boot, throw out everything — or do we make the call to cancel a game if there’s no realistic restart to do? It’s one of the things that makes us infamous for never hitting a release date, but it’s part of ‘gameplay first,’ ” a key principle at Blizzard.

“The Back to the Drawing Board concept has applicability across all industries,” said innovation educator Wartenberg. “Start over if a product is not turning out right.”

“The idea that we have spent so much so we should just keep going is a bogus one. If it’s the wrong approach, past spending should not be part of the decision process,” he said.

Wartenberg outlined a Phase Gate method for developing products, which establishes a standard procedure for cancelling projects that aren’t working out.

“At each gate, the decision to stop, go or modify should be made based on achievement of specific identified points. (Will meet market window? Design-to-unit production cost is within profitability range? Customers will want it? Etc.) Some large product companies refer to the decision at each gate as the ‘Kill Switch,’ even though it’s not called that in their official documentation,” he said.

5. DESIGN FOR DIFFERENT KINDS OF CUSTOMERS

Blizzard designs its games to appeal to a variety of customers — players from different cultures, in different settings, and with different personalities and experience.

In the recent panel discussion, Blizzard executives focused on how the company tailors its games for multi-national audiences — after making mistakes based on game developers’ inexperience with different cultures.

Frank Pearce, executive vice president of product development, told of a Japanese panda character that an artist drew for Warcraft III.

“He drew this Samurai panda. Turns out the Japanese and the Chinese aren’t big fans of each other, and the Chinese people objected to this animal of theirs being dressed in Japanese garb. So we had to change it,” Pearce said.

CEO Morhaime added, “Living here in the United States, we kind of had a North American focus. We had to catch ourselves when we weren’t considering that we have players all around the world.”

Pearce explained a variation that Blizzard adopted to allow players to experience World of Warcraft in commercial game parlors, especially in Asia.

“People don’t just play the games at home. They play the games in game rooms in China and Seoul, where it’s a totally different payment model, too. It comes down to, if you want to be successful globally, you have to think about what markets you want to go into.”

“One thing we do is send game charges to the account you play on, not to your computer. It’s a small thing, but it really helps people play in that game room environment,” he said.

World of Warcraft lead producer Brack said his teams focus on making sure the game appeals both to high-level and to low-level players. That’s part of what game developers think about when they make plans for new dungeons, new raids and new monsters, he said.

To improve the game’s appeal to experienced players, Blizzard is planning to add 10 additional experience levels as part of its upcoming Wrath of the Lich King expansion pack, he said. The top level, which is currently 70, will increase to 80, he said.

In addition, Blizzard will give players new ways to customize characters, including new hairstyles, he said. That’s aimed at increasing the game’s appeal to “social players,” including many women, who are interested in creating a unique look for their characters, he said.

6. THE IMPORTANCE OF FREQUENT FAILURES

“One of the mantras that a large software development company uses is ‘Fail Often, Fail Fast,’ ” Wartenberg said.

“As Alan Mullaly said when he led Boeing Commercial Aircraft, ‘We celebrate mistakes; bring them into the open, because we can’t help fix what we don’t know about.’ ”

To show Blizzard’s devotion to this principle, CEO Morhaime and other executives listed the titles of canceled games Blizzard had worked on: Nomad, Raiko, Warcraft Adventures, Games People Play, Crixa, Shattered Nations, Pax Imperia, and Denizen.

“We don’t have a 100 percent hit rate. We just cancel all the ones that aren’t going well,” Morhaime said.

“Failure begets success,” intellectual property attorney St. George said. “Many successful companies and CEOs have noted that their best successes have come from failures. The lessons learned from failures will provide the stepping stones for the next innovation.”

7. MOVE QUICKLY, IN PIECES

“In today’s rapidly moving market, the only way to get products out is to use various rapid prototyping methods to build products or services and try them in controlled pilot groups and then change as you go along,” Wartenberg said.

“A new concept in software development – dubbed ‘Agile’ methods, which includes techniques called Scrum, XP, etc – basically forces developers to build in small increments, review with the clients and continually iterate the design until the customer is satisfied.”

At Blizzard, small teams focus on narrow elements of the game. For example, different teams of artists specialize in trees, rocks, the game environment, and monsters, said lead producer Brack.

Multi-disciplinary “strike teams” serve as critics of how the different aspects of the game work together.

Raman Unnikrishnan, dean of the College of Engineering and Computer Science at CSU Fullerton, said:

“With entertainment software and online services, it is all about understanding what the gamers want and then proceeding to incrementally deliver that unmet need. The developers cannot follow a traditional waterfall style development (First requirements, then design, implementation, verification and finally maintenance) because they have millions of software users whose allegiance depends on the ability of the software developer to deliver new user-demanded features quickly and reliably.”

Quick work doesn’t mean that Blizzard will introduce a game before it’s ready, said Blizzard PR representative Bob Colayco. As evidence, he noted the release date of Diablo at the end of December 1996. Because Blizzard insisted on getting the game right, it missed the entire holiday shopping season, he said.

Diablo was a critical and sales success, proving to Blizzard that getting the game right was more important than meeting a deadline with a flawed product.

8. STATISTICS BOLSTER EXPERIENCE

“Innovation and player behavior have to be the focal point of Blizzard’s business model,” said Don Hicks, executive director of the AEA high-tech trade group in Orange County. “I am certain they have figured out how to monitor and measure player behavior, and have outlined an innovation process.”

When Blizzard’s game designers sit down to figure out whether a game can be improved, they have more to go on than just their personal game-playing experience and other players’ comments.

Statistics also help Blizzard find ways to make games more enjoyable.

Many statistics are automatically generated, such as what kills the most players and what is killed most by players, Brack said.

That helps game designers determine whether the game’s various monsters and classes of characters are fairly balanced.

Class designers hold regular meetings to decide whether to adjust the strengths of different classes to keep the game fair, Brack said.

9. DEMAND EXCELLENCE OR YOU’LL GET MEDIOCRITY

“We could ship a sub-par game, but ultimately it hurts the brand. We should ship it when it’s ready or we shouldn’t ship it at all,” said Pearce, the executive vice president of product development. “It’s an issue of making sure we’re not risking long-term gain for short-term benefits.”

Brack added: “That’s a core value of Blizzard, not a luxury that it can afford now that it’s bringing in so much revenue.”

“Living with mediocrity can be the downfall of a company or service firm,” said St. George. “There are many companies that have learned this lesson through failed product lines and even company closures. Requiring or demanding quality and excellence is a must for all companies and service firms.”

“Demanding excellence is a tough call, as it often requires that we accept ‘good enough’ to meet tough shipping schedules. The concept of ‘perfect’ is one that most cynical employees will laugh at,” Wartenberg said.

“But one of our local companies, QLogic in Aliso Viejo, has that exact title posted through out their facility – a big sign saying ‘Perfection: Our Clients Demand It.’

“If you ask for excellence or perfection, you many never get it, but you will sometimes get something approaching it – and mostly will get good enough. If you ask for good enough, however, you will never get anything approaching excellence and will often get below-average results. People tend to rise to meet expectations,” Wartenberg said.

10. CREATE A NEW TYPE OF PRODUCT

Blizzard was one of the pioneers in a new category of game – massively multi-player online role-playing games.

[That's a controversial statement, which is discussed in a follow-up post, "How innovative is World of Warcraft creator Blizzard Entertainment?" and in many comments below.]

In addition to Blizzard’s original product line – the game software itself – the company created a new type of product line by selling ongoing subscriptions for online access to the game, said Unnikrishnan at CSU Fullerton.

Blizzard remains ahead of the competition because the company was able to parlay its strength in one game format to create an online service, which created a whole new product line and different type of revenue stream,” he said.

In Asia, where gamers typically play World of Warcraft in Internet cafes, Blizzard uses a variation on monthly subscriptions, which wouldn’t work well in that setting. Instead of subscribing with a monthly payment, gamers purchase prepaid cards. In addition, in China Blizzard has licensed World of Warcraft to the publicly traded entertainment company The9, which also runs other online games.

11. OFFER EMPLOYEES SOMETHING EXTRA

Working at a computer-game company can be fun, but that’s not the only type of company that can benefit by providing employees with more than just a paycheck. Any innovator needs something beyond just monetary incentives.

“One advantage that Blizzard Entertainment has over many product organizations is the high degree of ‘fun factor.’ For young programmers, getting paid to develop what you love doing anyway is ideal,” Wartenberg said.

He added, “The trick is how to take the techniques that are so successful for Blizzard into other industries. It’s relatively easy in the life science field, in that the companies can replace fun with a deep sense of purpose and high societal value of the products delivered. For many engineers and life scientists, this is what drives them and allows them to work on very long-term projects without getting too discouraged.”

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

史玉柱:慎用“空降兵” 我 的投资范围很窄

No comments September 27th, 2009

史玉柱:慎用“空降兵” 我 的投资范围很窄
慎用空降兵

这么多年我自己最深刻的体会就是团队要自己培养。我是1989年8月份开始创业的,最初就4个人,最后留下了2个,到1990年时我的规模还很小,有十几个人。公司开始要上100人的台阶时,进来了一些之后成为我的骨干的员工——比如刘伟,她现在做到了巨人网游的总经理,应该算是最老的一批。那个时候我们还没有自己的公司,挂在深圳一家贸易公司名下,巨人集团成立是1992年的事情了。

我们公司从创业到现在,走的人也非常多,走的人中间有优秀的,但留下的人中优秀分子更多,像刘伟这批人。当然现在能干的人到外面找也能找出来,但能干、人品又好就难找了,而且很难有那种默契,后者是靠多年磨合获得的,我们的团队有些都配合了十几年了。

我的团队主要靠自己培养,我觉得一棵参天大树,必须有深扎在地下的根,这种树是最不怕大风的。我过去也不赞同空降部队,但不是象现在这样坚决,现在除了象CFO这种特别专业的人才外,我会尽量多使用自己公司内部培养起来的员工。用空降部队成功的几率很低。但用自己人在一个小的天地里容易低估自己,老是想外面的人很牛,实际上那个人还不如自己。

公司现在的很多高层,比如几位副总裁——费拥军、陆永华等也是在公司一步步培养起来的。除了老巨人的高管,现在巨人网络的高管也都是在进入网络游戏产业后,一步一步培养起来的。公司的技术副总袁晖、首席技术官宋仕良、《征途》和《巨人》两个事业部的负责人等,都是这几年摸爬滚打在一起,他们不断表现出优秀的品质和超强的能力,从很低的岗位走上管理岗位。严格意义上的空降部队我从来没有用过,但和很多企业家交流,感受到很多企业用空降部队的问题和矛盾。

在培养团队方面,我想首先是要尊重他们,不能因为自己是老板就觉得他们比你低;其次,他们有困难的时候要帮助解决;另外,有利益的时候不要忘记他们,给他们的报酬要超出大部分人的预期。

有用的企业文化

一个企业会结成怎样的果实跟企业文化关联很强,可以说企业文化是土壤。企业文化都是我自己总结,自己写出来的,然后开会向大家灌输。1997到2000年这几年我全面主持工作,开会很频繁,基本上一个月开一次全国经理会议。开会前一定是大家先起立背诵我们的“五条”——“说到做到、只认功劳、严己宽人、敢担责任、艰苦奋斗”,结束时再背一次。可以说这个形式非常不好,但是在灌输的时候,必须要采用这种方法。我们新招的人很容易记住这五条。我们这个办法很土,但是我认为它很管用。原来我在珠海巨人集团的时候企业文化是什么,是“要做中国的IBM”,后来我发现这是非常害人的一个空想,制定了一个很虚的目标。它在鼓励什么,鼓励大家搞大跃进、搞浮夸,让大家心里面很浮躁,对于现实没有什么帮助,现在我就不搞那个宏伟的目标了,我觉得实用最关键。企业文化要脚踏实地,真正对企业有所帮助,没有帮助的东西、给别人看的东西千万不要搞。企业文化起什么作用?我觉得最主要的就是到达管理上的盲区。

巨人网络现在的文化也是“说到做到、只认功劳、严己宽人、敢担责任、艰苦奋斗”,早就不是在珠海的时候那种“要做中国的IBM”了。现在的企业文化是我有一次在黄山太平湖向柳传志请教之后定的,一直沿用到现在。

这几句话仍是今天我们企业文化的精华。很多人说这几话“土气”,别人可能会认为这是在批评我们不够时尚、洋气,我却觉得“土气”是一种褒奖,土是最实在最本质的东西,做企业不是做秀,应该干企业最本质的事情,扎扎实实把企业自己的事情做好,是对员工、股东、自己以及社会最好的交代。

三道关

现在脑白金已经做了11年,有1万人,直到今天这些人还保持着极高的创业激情。我可以非常自信的说,大年三十中午他们还都在全国1800个县、300多个市的商场里做促销。很多同行们看到这种激情觉得不可思议。

商业的成功其实主要是在一些关键节点上,可以说不论是做网游还是做保健品,他们中总有相通的那部分。做保健品要想成功必须过三道关,有一道没过去就完蛋。

第一是产品关。这个产品一定要科学,是好东西。脑白金的实际组成很多人是陌生的,但黄金搭档很多人不陌生,其实就是复合维生素,补中国人缺的维生素和矿物质。但保健品的关键是服用后效果可以感受得到,这个不是从科学的角度出发,而是从营销的角度出发。这一点我们是有反思的,比如在脑黄金产品上,它的确是好东西,用来补充大脑的营养,但是它有一个缺点,吃过之后没感觉,结果市场上大家就骂这个东西没有用。

第二是市场策划关。你的产品怎么卖,怎么定位,你对消费者了解不了解?能否确定最精准的诉求,能否找到最准确的市场定位?像“今年过节不收礼,收礼只收脑白金”这个广告起源于对消费者的调查。当时,我在武汉做市场调查,在一个公园里找一群老头老太太聊,问他们吃不吃保健品。我们发现老年人还是信保健品的,但是吃不起,他们舍不得花钱,但希望儿女给他买,这在中国是个普遍现象。所以我们的广告实际上是对子女说话。后来我们调查下来,我们的消费者中间75%的产品是子女送给父母的。

第三团队关。产品再好,策划再好,团队执行能力不行同样会失败。

以前我们做市场调研时,是骑着自行车大街小巷地转的,因为骑自行车可以抄近路。脑白金在尼尔森的调查中,他认为我们在全国各地做的广告投放金额有三四十亿,但其实我们一年投放只有三亿,加上终端包装等一年投放差不多在5亿左右。为什么会有这么多的差距,这就是靠团队,比如与国际品牌在中国做广告的成本相比,我们的价格不到他们的十分之一。

我要求我的团队必须最大程度地降低成本,这样他们就会琢磨,我们怎样使用广告时间?一般电视台广告能卖掉70%就不错,大部分卖不到一半,签约的客户突然不播了,那这一段(时间)电视台就是空的。我们把这个时段要下来,当然价格就很低了。我们的团队在降低成本方面有很多很多创新的思路、方法,他们的执行力也是这样培养出来的。我在全国有300多家办事处,只要降低一点成本,不赚钱也就变成赚钱了。想一想,一年需要投30亿的广告因为团队执行力变成了3亿,我们利润空间一下子就出来了。

象这样的细节有很多。比如像脑白金的产品如何摆放,我们办事处的人会研究脑白金产品在商场里应该摆放多高,他认为1.5米以下不行,看不见,因为很多产品都在那个高度放着,最保险的高度是1.5到1.7米之间。可以说我们这个团队每天都在琢磨执行。中国很多企业都存在这个问题,这是我们传统文化带来的弊端。很多团队做事情失败了,都会找理由,越是成功率低的人找的理由越是冠冕堂皇,后来我们就只问结果不问过程,这样相对来讲我们成功率就高了。

另外对于零售企业来说,你要把第一家店做好,哪怕用一年的时间,把所有的手册都做好,你的新员工哪怕是小学毕业、初中毕业都能按照手册来干,然后第二年再在资本推动下开10家店、100家店都不是问题。这叫试销市场快不得,全国市场慢不得。

刚才说的脑白金只是一个例子,其实其他行业也一样,你的产品、市场策划、团队,这三个环节决定了一个公司能否成功。

所以说一个企业产品的成功是靠团队的心血灌输出来的,这个东西没有什么捷径。我一直坚信天下掉不下来桃子,要想有桃子的话,就要靠一点一点的浇灌,该打农药打农药、该施肥要施肥、该浇水要浇水才行。

我的投资范围很窄

很多人对于我为什么做网游感到非常疑惑。我做网游是历史形成的,因为我们的核心团队以前都是做IT、软件的人。我们转行做保健品是迫不得已,但这些人本行是IT。我是程序员出身,我喜欢编程,我们这些人对IT是有感情基础的,有这么一个土壤,后来才开始做网游,如果我们是土生土长做保健品的,也不会有巨人网络公司的诞生了。

我那个时候失业了,刘伟他们把公司管得很好,我不需要插手。我们也刚撤下来做银行的投资,我没事可干,就玩游戏,渐渐对游戏越来越热爱,最后甚至上班也在玩游戏。刘伟他们进我办公室开会,一看我在玩游戏就讽刺我两句不务正业。后来我对游戏了解到一定程度后,就跟刘伟提出来我要投资网游2000万,居然他们全部都举手通过了。

其实投资不是那么简单,以前我提议的投资基本上都被他们否定掉了。当时想投新浪,是因为吴征要退,想让四通接,但四通没有现金,老段找到我说你把他买下来吧,结果我开会和大家商量最后被否定掉了。还想投手机,当时绝大部分人都反对,也被否决了。再之后安徽省政府想要退出奇瑞汽车,2001年政府领导来找我,问我愿意不愿意接,这些又被团队否决了。后来我提投网络游戏要2000万,居然全部通过,这又很意外。

我们投了2000万,钱花完了游戏还没做出来。这时候公司已经负债300万,账面是零,300万服务器的钱还没还。我们评估了一下,到产品出来并且能赚钱,还需要再投2000万。我占75%的股份,最早的2000万里面有1500万是我的,另外500万是我借给当时团队的,按照有限责任公司同比例再增资的原则,我要再投1500万,团队再投500万,但这个时候他们的钱不多,就不投了。后来刘伟他们脑白金的早期团队也认购了一些股份,上市后价值增加了几百倍。

我的投资原则是公司的日常经营、人财物管理这些东西我都不管,都是刘伟他们管。我现在和外界接触也不多,投资51.com我花的精力也不多。相对来说接触到我的人是非常少的,大部分项目在刘伟那儿就被卡死了,只有过了刘伟这关才能到我这儿,我才会见面。

《赢在中国》的那些项目我肯定不会投的,投资我有自己的纪律,哪些行业投、哪些行业不投,除了金融和互联网,其他行业我基本不碰。当然也要看人,但人再好,不是这两个行业也不行,我投资范围比较窄。

在这个新人辈出的年代,投资机会越来越多,但是对于很多企业家来说,难的是如何面对诱惑,我的想法是看准了、研究透了再投。

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

关于无授权领导能力

No comments September 25th, 2009

第2点无授权的领导能力。

不仅仅是作为产品经理,其它任何职位,在解决很多问题的时候,尤其是跨部门、平级之间的沟通,这种能力对最终事情的能做成与做不成、怎么做成就有着非常重要的作用了。

原文:

优秀的产品经理

1、沟通能力
优秀的产品经理一定是个成功的沟通者, 沟通能力包括口头沟通能力和文字沟通能力。产品经理的一个最主要角色是做为沟通的中心,
产品经理的沟通能力不仅体现在和不同工作岗位的人进行有效沟通,同时还体现在如下方面:

和不同个性的人沟通。例如,大部分工程师的性格偏内向,而大部分销售和市场人员则很外向
和不同工作岗位的人沟通时采用不同的”语言”。如果要进行高效沟通,很重要的一点是说沟通对象关注和易于理解的”语言”。比如,在和市场人员沟通和与工程师沟通时,要采用不同的沟通方式:对于市场人员说太多诸如”数据库性能”、”内存管理算法”之类的东西,无疑会让他们郁闷不解;而对工程师谈话过于概念化,也无助于他们设计真正的实现细节;类似的,在同老板们沟通时,则应该更多聚焦在较高的层面上,避免过于深入细枝末节的事情。

2、无授权领导能力
成功的产品经理是优秀的领导者,即便是没有明确的授权。
产品经理通常需要在多个领域执行领导工作,包括领导项目团队、领导产品战略和蓝图指定,以及领导跨团队的产品活动等。但是在大多数情况下,产品经理通常没有得到公司正式的授权。此时,是否具有”无授权领导能力”就成为成功与否的关键。
如何在无授权的情况下领导团队,我的建议是–综合运用影响力、协商、人际关系及其他类似技能
3、学习能力
IT产业是一个快速变化的产业,”不变的也许只有变化”,新技术不断涌现,今日的新产品在几个月后就会变成大路货,甚至更快。优秀的产品经理必须能够快速学习,即便是在比较新的领域。具备此能力才能相对容易地在不断变化的市场和技术趋势下管理好产品。.很多公司在招聘产品经理的时候会犯一个错误–他们过分看中既有经验。比如,一个公司要做安全软件,他们就回在招聘时说明”需具有安全软件领域5年以上工作经验”。这其实是个错误的方法,更好的做法是寻找在软件领域有工作经验的产品经理,同时善于快速学习。
4、商业敏感度
优秀的产品经理对商业有极好的感觉,他们清楚如何发现市场机会,了解竞争差异化的重要性,并能提出制胜的产品战略、定价、推广策略、合作计划以及盈亏分析等。
看到这些,别以为产品经理就该是MBA毕业。实际上,大多数优秀的产品经理并没有上过什么MBA,但是他们对商业有很强的敏感。
5、热爱产品
优秀的产品经理对产品有发自内心的热爱。他们孜孜不倦地尝试各种新产品,注册各种产品的测试版,下载产品的试用版并仔细揣摩,一有时间就去网上看各类新产品的网站。他们对设计优秀的产品喜爱有加,即便这些产品并非自己公司的;他们鄙视那些没品的产品,即便那是自己公司开发的。最重要的是,他们醉心于创造优秀的产品–无论是全新的产品或是既有产品的改进。
6、注重细节,追求完美
优秀的产品经理对细节孜孜以求,注重细节是开发优秀产品的最重要先决条件,正所谓”细节决定成败”。Steve Jobs曾说:
iMac笔记本并非只是透明颜色和外壳外形与众不同,这个产品的核心理念在于成为最精致的消费电脑。
在最新的iMac中,我们坚决去掉了散热扇,因为我们认为使用一台不嗡嗡作响的电脑工作更令人愉悦。当然,并不是我决定就可以取消散热扇,它需要工程师们付出巨大的努力,找到管理电源和散热的更好办法。这是产品设计之初就存在的核心理念。
这也是用户愿意选择我们产品的原因–追求每个细节的完美,从而能让用户更方便愉悦地使用他们的电脑。
优秀的产品经理不但注重产品设计的细节,在其他事情上一样追求完美,比如进行竞争状况分析、制作项目计划,以及所有其他自己负责的工作。
7、日常产品管理能力
优秀的产品经理具备良好的日常产品管理能力,包括:

撰写市场需求文档(MRD)和产品需求文档(PRD)
进行竞争状况分析
规划产品路线图
制作产品演示PPT
设计用户界面
分析产品数据等.
以上这些核心能力不但有助于产品经理的自我提升,同时对于招聘产品经理也有参考价值。
如果你对产品经理的职责有补充,欢迎给我来信,也可在评论中发表高见。

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

软件开发的几个准则

No comments September 24th, 2009

从讲Iphone APP开发的文章里截出来的,其实做其它东西也是一样的~~~

1.了解你的用户,并与他们接触、交谈。  

2.不要做虚幻的想象的设计,多从成功软件中汲取经验。  

3.软件要设计得“小”。  

4.找到足够多的设计方案,通过数量的累计来得到好的质量。  
5.失败得越早成功得越快。  

6.要做到像素级精确。  

7.记住没有什么是非常宝贵不能舍弃的,不要害怕去修改。  

8.在提交之前进行足够的测试。

 

原文也很精彩,也贴下来.

成功开发iPhone软件的10个步骤

一年前斯坦福和Apple联手推出了基于iPhone平台的开发课程,这个课程的ppt被放在网上分享,反响非常好。这个学期,斯坦福将课程进行了录像,放在了iTunes university上提供下载,目前这个课程在iTunes的下载排行第一,达到了100万人次的下载。这次给大家分享的是其中关于“成功开发iPhone软件的10个步骤”的讲座,虽然与我们工作中设计软件的应用平台不同,但是还是有很多成功的经验可以借鉴。

1. 决定要做什么

  人们很容易犯的一个错误是“从结论出发”,比如决定要做一个本地社会关系网的软件,而没有去想究竟做这个软件是想解决什么问题,是为了解决和好友找地方吃饭的问题还是别的什么,如果是针对吃饭地点问题,那么是不是有更加好的解决方法。所以首先要确定的是需要满足什么样的目标用户和需要解决的问题。

1

  最容易成功的一种情况是设计者本身就是目标用户,而要解决的问题也是设计者本身遇到的问题。这样设计者能够经常使用软件,发现其中问题并进行有效迭代。想象别人的需求很困难,必须与目标用户接触、交谈,使用用户研究工作中经常使用的用户画像方法。用户画像并不一定是真实用户,可以是虚拟的,但是要能够代表用户群体。

2. 访问app store

  iPhone上的软件设计者没有多少机会去教育用户熟悉新的设计,这是由于iPhone本身的使用环境限制的,用户的注意力时间有限,耐心也有限,很多时候都是在交通工具上或者在等待的间隙使用的,所以软件的设计是需要用户一看就知道如何使用的。App Store上有非常多的软件,找出热门软件,看看它们是如何设计的。这些热门软件一般都是经过精心设计的,并且通常都是得到用户反馈迭代过几轮的,一些共通的地方可以借鉴参考。“Good artists copy, great artists steal.”

3. 搜寻所有可能的设计方案

  有的时候设计师心里有一个设计方案,觉得这个方案非常完美,不愿意去考虑是不是有别的设计。但是通常第一个设计方案都不是完美的,即使是苹果的设计师,第一个方案往往都是糟糕的。

  Iphone上的软件有很多局限性:
  1. 小屏幕
  2. 触摸式的输入很不精确,通常需要44像素大小的目标才能有足够的点中率。
  3. 输入更困难,即使有软键盘,相对普通键盘的输入还是困难不少。更多的是传达信息给用户而不是让用户产出信息。简单地说就是读应用多于写应用。
  4. 使用时间比较短,通常一次都是几分钟的使用长度。不一定是用户对软件不感兴趣,而是由一些例如“地铁到站了”的客观情况所决定的。所以设计出的软件一个操作流程不能花很长的时间。

  以iPhoto为例,下图左侧为mac上的iPhoto程序,功能非常全面,编辑图像的能力很强。而右侧是iPhone端的程序,主要的功能是看图。

  不能因为功能上的减少就说iPhone端的iPhoto不成功,事实上它是一个非常成功的软件。任何人即使是3岁的孩子也会使用它,它的核心思想就是“小”。只保留那些核心功能,如果缺失了用户就不再使用此软件。

4. 画草图

  到了这一步,就需要在纸上画出草稿了。例如下图右侧的程序大致对应的草图在左侧。

  在做草图的时候尽量多地设计,不同的功能不同的布局。这个是苹果设计师进行设计的方法(creative alternative design),画出的第一个草图是设计师心里一开始最理想的方案,做第二到第四个的时候还比较简单,做到第七个就比较难了,最后三个是非常难的,但也是价值最大的,往往有非常有创意的想法迸发出来。

  当有了这些草图以后,需要寻找到目标用户去听他们的意见,比如有同样需求的朋友。他们会反馈一些意见,喜欢什么设计不喜欢哪些地方,这些意见有助于将设计方案进行排除和整合。剩下大约2-3个接受度比较高,没有明显优劣的方案,可以选择一个方案来实现。在这部分花的时间比较多,但是非常值得,因为在之后的过程中不断修改所付出的代价往往是在先期修改的代价的数倍。

5. 建立纸质原型

  下图中的每张纸代表了一个屏幕上显示的软件界面。这个步骤的价值在于在纸上绘制这些图后就可以得到一些用户实际使用的感受而不必等编程实现。

  从第一张开始“OK, 你刚刚打开我的软件”,点击这个按钮就到了第二张纸的屏幕,等等就可以对软件的整个操作流程有直观的感受了。在这个过程中可以收集到比草图阶段丰富得多的用户反馈,哪里用户不知道怎么操作了,哪里容易引起困惑,哪里用户比较喜欢,哪里不喜欢。

  下面这张图是一个iPhone游戏的设计师们做的纸质的原型,模拟真实的iPhone。设计师们做了各种各样的纸片来模拟程序中的各种元素。

6. 工具的使用­——omnigraffle

  Omnigraffle虽然是个图形编辑软件,但是更加合适做原型设计,里面有丰富的控件库,可以拖拉这些控件来方便地搭建程序界面。一些比较个性的设计或者比较细节的加工可以在photoshop中制作。下面这张图是omnigraffle中用于Iphone平台的控件库。

  下面这张图是讲师用omnigraffle做出的软件界面,可以实现到与最终版本像素级精确。

  在这个阶段就要进行一些比较细节的内容确定和视觉相关定义,比如颜色的定义等等。建立起精确的原型也方便一个团队多人一起工作,减少沟通成本,避免产生歧义。

7. 回溯修改

  其实不是一个真正的步骤,但是放在这里说明并不是每个软件都要一步到位,其实是一个迭代的过程,有时候必须要回溯修改。

  下图是讲师最近正在制作的一个软件的界面,在制作具体界面细节中所进行的不同尝试:

  也有要进行更加彻底的回溯修改的情况,有的用户在草图阶段反馈说喜欢的东西其实并不是他真正需要的东西,这种情况下就要回到草图阶段进行重新设计。

8. 开发实现

  这部分不赘述,简单地说就是要注意程序的设计模式,用户界面和后台数据分离。

9. 测试

  对软件做测试,看看是否文字提示恰当,是否有bug等。这里比较关键的是谁来做测试。

  好友是比较可靠的资源,他们的反馈比较有价值。但是如果本地的目标用户比较难找,比如地震分析软件这种涉及全球性质的用户,就可以使用Mechanical Turk。Mechanical Turk是Amazon的一个服务,对于那些在网上又没有明确事情要做的人,以非常低的报酬,比如几美分,来请他们进行测试。也可以出稍高的价钱请数量比较少但是比较专业的人来进行测试,这样反馈的价值比较高。

10. 发布

  发布软件,在比较前期的版本可能需要界面修改,bug修补,迭代版本。但是通常到后期都是一个比较可喜的结局。

总结

  几条要注意的原则:

  1.了解你的用户,并与他们接触、交谈。
  2.不要做虚幻的想象的设计,多从成功软件中汲取经验。
  3.软件要设计得“小”。
  4.找到足够多的设计方案,通过数量的累计来得到好的质量。
  5.失败得越早成功得越快。
  6.要做到像素级精确。
  7.记住没有什么是非常宝贵不能舍弃的,不要害怕去修改。
  8.在提交之前进行足够的测试。

原文链接:http://cdc.tencent.com/?p=1433

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

决定IBM命运的45分钟

No comments September 24th, 2009

在1929年开始的那一次大萧条中,IBM凭借着创始人老沃森的远见卓识脱颖而出。随后,IBM开创并引领全球信息技术产业长达60余年。

直到1992年,骄傲自满致使IBM跌入低谷,公司濒临被解体的边缘。

关于此时的IBM,《电脑大战》一书有这样的描述:“比尔·盖茨曾经说过,IBM将在几年之内倒闭。盖茨的话或许是对的。自从1980 年以来,IBM就是一个失败者,一个几乎在所有电脑技术领域都落后的失败者。传统的大型电脑并没有在一夜之间消失,但它们却已经是过时的技术了,而且,它们曾经在其中引领时尚的王国也已经萎缩。”

即便是《经济学人》这本谨慎的和可信赖的杂志也在连续6 周的时间里,发表了与IBM 有关的3个主要报道和一段长篇编者按。“萦绕在该公司周围的还有两个问题”,该编者按写道,“在一个以迅疾的科技变革为推动力的并不断涌起小型和微型公司的行业中,一家拥有像IBM这样规模的公司——尽管它组织完善——能够迅速应变竞争环境吗?还有,IBM能从急剧下滑的电脑主机市场(IBM正是依靠这一市场赚取了大量利润)上转向从诸如电脑服务和软件等这些扩张中的市场份额中赚取利润吗?……这两个问题的答案或许是:不。”

幸运的是,所有的这些专家预言都没有成为现实。

45分钟

1993年3月,IBM聘请郭士纳为董事长兼CEO,在随后的10年间,郭士纳带领IBM重回巅峰,不仅仅恢复了IBM的创新精神和运营效率,更重要的是完成了从制造业向服务业的华丽转型。至今,IBM的营业收入已经突破1000亿美元,其中90%的利润来自于软件和服务,只有9%的利润来自于电脑硬件及其系统。

从硬件到软件和服务,IBM的转型历经10年,然而其关键时刻却只有45分钟。

让我们回到1993年3月25日,这天距离郭士纳正式履职还有4个工作日。当天出版的《商业周刊》在封面上介绍了郭士纳就任IBM董事长兼CEO的消息。郭士纳事后回顾说,那一天是他个人职业生涯最关键的一天,也是IBM十年转型最重要的一天。

当天下午,郭士纳与IBM的50人核心管理团队见面。正襟危坐的IBM高级主管除了一句“欢迎,我很愿意成为您的管理班子中的一员”这句客套话以外,再没有其他什么了。于是郭士纳不得不打开自己的话匣子。他首先告诉在座的各位,他并不是主动找到这份工作,而是接受邀请承担这份工作,实际上是承担一个责任,并且准备与各位共同承担这个挽救一家曾经伟大的公司的责任。

郭士纳继续说:“如果有必要,我会从外部引进人才。但是,你们中的每一个人都最先有机会展现你们自己的才能,而且我也希望你们能给我一些时间来证明我自己的能力。每个人都是站在新的起跑线上,你们过去所取得的成就或遭受的失败都与我无关。”

管理哲学8要点

就是在这个会上,郭士纳阐述了他著名的管理哲学8要点:

1. 我按照原则而不是流程程序管理。

2. 市场决定我们的一切行为。

3. 我是一个深深地相信质量、强有力的竞争战略与规划、团队合作、绩效工资制和商业道德责任的人。
4. 我渴求那些能够解决问题和帮助同事解决问题的人,我会开除那些政客式的人。

5. 我将致力于战略的制定,剩下的执行战略的任务就是你们的事了。只需以非正规的方式让我知道相关的信息。不要隐瞒坏消息,我痛恨意外之事;不要试图在我面前说谎;要在生产线以外解决问题,不要把问题带到生产线上。

6. 动作要快。不要怕犯错误,因为即便是犯错误也要由于我们动作太快而不是太慢。

7. 我很少有等级制度的观念。无论是谁,也无论其职务高低,只要有助于解决问题,大家就要在一起商量解决。要将委员会会议和各种会议减少到最低限度。取消委员会决策制度,让我们更多一些坦率和直截了当的交流。

8. 我对技术并不精通,我需要学习,但是不要指望我能够成为一名技术专家。分公司的负责人必须能够为我解释各种商业用语。

然后,郭士纳向核心管理团队提出了未来90天中的5件要事:

1. 暂时冻结流动资金。我们就要面临着流动资金短缺的危险。

2.确保我们将在1994年实现盈利,并向全世界以及IBM各分公司传个口信:公司的经营业已稳定。

3.开发和实施1993 年~1994 年的关键客户战略,这将会使客户相信,我们又回来为他们的利益提供服务了,而不是强迫他们接受我们的产品(电脑主机)来减缓IBM自己短期的财政压力。

4. 在第三季度开始的时候要完成精简裁员任务。

5. 开发一个中期的商业战略。

最后,郭士纳对这5个90天优先任务做了分配,并要求每个分公司的负责人提交一份10页的报告,报告内容包括顾客需求、产品种类、竞争力分析、技术前景、经济情况、长期和短期的关键问题以及1993年-1994年的发展前景。同时,郭士纳还要求所有与会者描述他们对IBM 公司的总体看法:我们将采取什么样的短期步骤以进一步加强客户关系、提高销售业绩以及应对竞争性进攻?我们应该如何思考我们的长期和短期商业战略?

在这次会议之后,郭士纳为IBM确定了新的核心价值观:
1. 力争取胜(Win):所有的IBM的员工都有必要认识到,做生意是一个具有竞争性的活动,要么成功,要么失败,没有其他的选择。在新IBM中,那些缺乏竞争热情的人将找不到他们的适合位置。最关键的还是机会存在于公司在全球各地的各个分部,而不仅仅只存在于美国纽约阿蒙克总部。我们必须把市场确定为我们的所有行动和行为的动机。

2. 快速执行:这是一个有关速度和磨炼的事业。我们不能再执迷不悟做一个完美主义者了,因为完美主义会使我们错失市场良机,并会使其他竞争对手夺走我们的科技发明。不要再一味地进行死研究了,在新IBM中,成功的人士都是动手做事的人——而且是快速而有效做事的人。

3. 团队精神:要使IBM像一个团队一样进行运转——一个实实在在的团队。
“力争取胜、快速执行和团队精神”像一个警句一样通过多媒体传遍了全公司,并最终演变成公司的新绩效管理系统。所有IBM 的员工每年都要围绕这3个方面制定他们的“个人业绩承诺”(PBC),并列举出在来年中为了这3个方面的任务他们所需要采取的行动。直到今天,PBC仍是IBM员工绩效考评的核心。

在随后的几年里,IBM通过主机系统的策略性降价走出危机,并通过把握电子商务的契机,重回巅峰。

1993年4月1日,郭士纳上任当天,IBM的股价是12.58美元,当年年底升至13.98美元;随后的1994年-1999年,IBM的股价分别是18.18美元、22.60美元、37.48美元、51.76美元、 91.22美元、 107.88美元。可以说,至2000年IBM已经起死回生。

在《谁说大象不能跳舞》中,郭士纳回忆说:“当我回顾自己在IBM的9年任期中所持的观点时,我惊奇地发现,我所说的几乎都变成了现实。无论是媒体的报道、作为一个顾客的感受、还是我自己的领导原则、所需要完成的以及已经完成的工作,几乎都在我正式开始我的IBM职业生涯4天之前的那个45分钟的会议上讨论过了。”

Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)

Javascript Closures

No comments September 16th, 2009

Javascript Closures

Introduction

Closure
A “closure” is an expression (typically a function) that can have free variables together with an environment that binds those variables (that “closes” the expression).

Closures are one of the most powerful features of ECMAScript (javascript) but they cannot be property exploited without understanding them. They are, however, relatively easy to create, even accidentally, and their creation has potentially harmful consequences, particularly in some relatively common web browser environments. To avoid accidentally encountering the drawbacks and to take advantage of the benefits they offer it is necessary to understand their mechanism. This depends heavily on the role of scope chains in identifier resolution and so on the resolution of property names on objects.

The simple explanation of a Closure is that ECMAScript allows inner functions; function definitions and function expressions that are inside the function bodes of other functions. And that those inner functions are allowed access to all of the local variables, parameters and declared inner functions within their outer function(s). A closure is formed when one of those inner functions is made accessible outside of the function in which it was contained, so that it may be executed after the outer function has returned. At which point it still has access to the local variables, parameters and inner function declarations of its outer function. Those local variables, parameter and function declarations (initially) have the values that they had when the outer function returned and may be interacted with by the inner function.

Unfortunately, properly understanding closures requires an understanding of the mechanism behind them, and quite a bit of technical detail. While some of the ECMA 262 specified algorithms have been brushed over in the early part of the following explanation, much cannot be omitted or easily simplified. Individuals familiar with object property name resolution may skip that section but only people already familiar with closures can afford to skip the following sections, and they can stop reading now and get back to exploiting them.

The Resolution of Property Names on Objects

ECMAScript recognises two categories of object, “Native Object” and “Host Object” with a sub-category of native objects called “Built-in Object” (ECMA 262 3rd Ed Section 4.3). Native objects belong to the language and host objects are provided by the environment, and may be, for example, document objects, DOM nodes and the like.

Native objects are loose and dynamic bags of named properties (some implementations are not that dynamic when it comes to the built in object sub-category, though usually that doesn’t matter). The defined named properties of an object will hold a value, which may be a reference to another Object (functions are also Objects in this sense) or a primitive value: String, Number, Boolean, Null or Undefined. The Undefined primitive type is a bit odd in that it is possible to assign a value of Undefined to a property of an object but doing so does not remove that property from the object; it remains a defined named property, it just holds the value undefined.

The following is a simplified description of how property values are read and set on objects with the internal details brushed over to the greatest extent possible.

Assignment of Values

Named properties of objects can be created, or values set on existing named properties, by assigning a value to that named property. So given:-

var objectRef = new Object(); //create a generic javascript object.

A property with the name “testNumber” can be created as:-

objectRef.testNumber = 5;
/* - or:- */
objectRef["testNumber"] = 5;

The object had no “testNumber” property prior to the assignment but one is created when the assignment is made. Any subsequent assignment does not need to create the property, it just re-sets its value:-

objectRef.testNumber = 8;
/* - or:- */
objectRef["testNumber"] = 8;

Javascript objects have prototypes that can themselves be objects, as will be described shortly, and that prototype may have named properties. But this has no role in assignment. If a value is assigned and the actual object does not have a property with the corresponding name a property of that name is created and the value is assigned to it. If it has the property then its value is re-set.

Reading of Values

It is in reading values from object properties that prototypes come into play. If an object has a property with the property name used in the property accessor then the value of that property is returned:-

/* Assign a value to a named property. If the object does not have a
   property with the corresponding name prior to the assignment it
   will have one after it:-
*/
objectRef.testNumber = 8;

/* Read the value back from the property:- */

var val = objectRef.testNumber;
/* and  - val - now holds the value 8 that was just assigned to the
   named property of the object. */

But all objects may have prototypes, and prototypes are objects so they, in turn, may have prototypes, which may have prototypes, and so on forming what is called the prototype chain. The prototype chain ends when one of the objects in the chain has a null prototype. The default prototype for the Object constructor has a null prototype so:-

var objectRef = new Object(); //create a generic javascript object.

Creates an object with the prototype Object.prototype that itself has a null prototype. So the prototype chain for objectRef contains only one object: Object.prototype. However:-

/* A "constructor" function for creating objects of a -
   MyObject1 - type.
*/
function MyObject1(formalParameter){
    /* Give the constructed object a property called - testNumber - and
       assign it the value passed to the constructor as its first
       argument:-
    */
    this.testNumber = formalParameter;
}

/* A "constructor" function for creating objects of a -
   MyObject2 - type:-
*/
function MyObject2(formalParameter){
   /* Give the constructed object a property called - testString -
      and assign it the value passed to the constructor as its first
      argument:-
    */
    this.testString = formalParameter;
}

/* The next operation replaces the default prototype associated with
   all MyObject2 instances with an instance of MyObject1, passing the
   argument - 8 - to the MyObject1 constructor so that its -
   testNumber - property will be set to that value:-
*/
MyObject2.prototype = new MyObject1( 8 );

/* Finally, create an instance of - MyObject2 - and assign a reference
   to that object to the variable - objectRef - passing a string as the
   first argument for the constructor:-
*/

var objectRef = new MyObject2( "String_Value" );

The instance of MyObject2 referred to by the objectRef variable has a prototype chain. The first object in that chain is the instance of MyObject1 that was created and assigned to the prototype property of the MyObject2 constructor. The instance of MyObject1 has a prototype, the default Object prototype that corresponds with the object referred to by Object.prototype. Object.prototype has a null prototype so the prototype chain comes to an end at this point.

When a property accessor attempts to read a named property form the object referred to by the variable objectRef the whole prototype chain can enter into the process. In the simple case:-

var val = objectRef.testString;

- the instance of MyObject2 referred to by objectRef has a property with the name “testString” so it is the value of that property, set to “String_Value”, that is assigned to the variable val. However:-

var val = objectRef.testNumber;

- cannot read a named property form the instance of MyObject2 itself as it has no such property but the variable val is set to the value of 8 rather than undefined because having failed to find a corresponding named property on the object itself the interpreter then examines the object that is its prototype. Its prototype is the instance of MyObject1 and it was created with a property named “testNumber” with the value 8 assigned to that property, so the property accessor evaluates as the value 8. Neither MyObject1 or MyObject2 have defined a toString method, but if a property accessor attempts to read the value of a toString property from objectRef:-

var val = objectRef.toString;

- the val variable is assigned a reference to a function. That function is the toString property of Object.prototype and is returned because the process of examining the prototype of objectRef, when objectRef turns out not to have a “toString” property, is acting on an object, so when that prototype is found to lack the property its prototype is examined in turn. Its prototype is Object.prototype, which does have a toString method so it is a reference to that function object that is returned.

Finally:-

var val = objectRef.madeUpProperty;

- returns undefined, because as the process of working up the prototype chain finds no properties on any of the object with the name “madeUpPeoperty” it eventually gets to the prototype of Object.prototype, which is null, and the process ends returning undefined.

The reading of named properties returns the first value found, on the object or then from its prototype chain. The assigning of a value to a named property on an object will create a property on the object itself if no corresponding property already exists.

This means that if a value was assigned as objectRef.testNumber = 3 a “testNumber” property will be created on the instance of MyObject2 itself, and any subsequent attempts to read that value will retrieve that value as set on the object. The prototype chain no longer needs to be examined to resolve the property accessor, but the instance of MyObject1 with the value of 8 assigned to its “testNumber” property is unaltered. The assignment to the objectRef object masks the corresponding property in its prototype chain.

Note: ECMAScript defines an internal [[prototype]] property of the internal Object type. This property is not directly accessible with scripts, but it is the chain of objects referred to with the internal [[prototype]] property that is used in property accessor resolution; the object’s prototype chain. A public prototype property exists to allow the assignment, definition and manipulation of prototypes in association with the internal [[prototype]] property. The details of the relationship between to two are described in ECMA 262 (3rd edition) and are beyond the scope of this discussion.

Identifier Resolution, Execution Contexts and Scope Chains

The Execution Context

An execution context is an abstract concept used by the ECMSScript specification (ECMA 262 3rd edition) to define the behaviour required of ECMAScript implementations. The specification does not say anything about how execution contexts should be implemented but execution contexts have associated attributes that refer to specification defined structures so they might be conceived (and even implemented) as objects with properties, though not public properties.

All javascript code is executed in an execution context. Global code (code executed inline, normally as a JS file, or HTML page, loads) gets executed in what I will be calling a global execution context, and each invocation of a function (possibly as a constructor) has an associated execution context. Code executed with the eval function also gets a distinct execution context but as eval is never normally used by javascript programmers it will not be discussed here. The specified details of execution contexts are to be found in section 10.2 of ECMA 262 (3rd edition).

When a javascript function is called it enters an execution context, if another function is called (or the same function recursively) a new execution context is created and execution enters that context for the duration of the function call. Returning to the original execution context when that called function returns. Thus running javascript code forms a stack of execution contexts.

When an execution context is created a number of things happen in a defined order. First, in the execution context of a function, an “Activation” object is created. The activation object is another specification mechanism. It can be considered as an object because it ends up having accessible named properties, but it is not a normal object as it has no prototype (at least not a defined prototype) and it cannot be directly referenced by javascript code.

The next step in the creation of the execution context for a function call is the creation of an arguments object, which is an array-like object with integer indexed members corresponding with the arguments passed to the function call, in order. It also has length and callee properties (which are not relevant to this discussion, see the spec for details). A property of the Activation object is created with the name “arguments” and a reference to the arguments object is assigned to that property.

Next the execution context is assigned a scope. A scope consists of a list (or chain) of objects. Each function object has an internal [[scope]] property (which we will go into more detail about shortly) that also consists of a list (or chain) of objects. The scope that is assigned to the execution context of a function call consists of the list referred to by the [[scope]] property of the corresponding function object with the Activation object added at the front of the chain (or the top of the list).

Then the process of “variable instantiation” takes place using an object that ECMA 262 refers to as the “Variable” object. However, the Activation object is used as the Variable object (note this, it is important: they are the same object). Named properties of the Variable object are created for each of the function’s formal parameters, and if arguments to the function call correspond with those parameters the values of those arguments are assigned to the properties (otherwise the assigned value is undefined). Inner function definitions are used to create function objects which are assigned to properties of the Variable object with names that correspond to the function name used in the function declaration. The last stage of variable instantiation is to create named properties of the Variable object that correspond with all the local variables declared within the function.

The properties created on the Variable object that correspond with declared local variables are initially assigned undefined values during variable instantiation, the actual initialisation of local variables does not happen until the evaluation of the corresponding assignment expressions during the execution of the function body code.

It is the fact that the Activation object, with its arguments property, and the Variable object, with named properties corresponding with function local variables, are the same object, that allows the identifier arguments to be treated as if it was a function local variable.

Finally a value is assigned for use with the this keyword. If the value assigned refers to an object then property accessors prefixed with the this keyword reference properties of that object. If the value assigned (internally) is null then the this keyword will refer to the global object.

The global execution context gets some slightly different handling as it does not have arguments so it does not need a defined Activation object to refer to them. The global execution context does need a scope and its scope chain consists of exactly one object, the global object. The global execution context does go through variable instantiation, its inner functions are the normal top level function declarations that make up the bulk of javascript code. The global object is used as the Variable object, which is why globally declared functions become properties of the global object. As do globally declared variables.

The global execution context also uses a reference to the global object for the this object.

Scope chains and [[scope]]

The scope chain of the execution context for a function call is constructed by adding the execution context’s Activation/Variable object to the front of the scope chain held in the function object’s [[scope]] property, so it is important to understand how the internal [[scope]] property is defined.

In ECMAScript functions are objects, they are created during variable instantiation from function declarations, during the evaluation of function expressions or by invoking the Function constructor.

Function objects created with the Function constructor always have a [[scope]] property referring to a scope chain that only contains the global object.

Function objects created with function declarations or function expressions have the scope chain of the execution context in which they are created assigned to their internal [[scope]] property.

In the simplest case of a global function declaration such as:-

function exampleFunction(formalParameter){
    ...   // function body code
}

- the corresponding function object is created during the variable instantiation for the global execution context. The global execution context has a scope chain consisting of only the global object. Thus the function object that is created and referred to by the property of the global object with the name “exampleFunction” is assigned an internal [[scope]] property referring to a scope chain containing only the global object.

A similar scope chain is assigned when a function expression is executed in the global context:-

var exampleFuncRef = function(){
    ...   // function body code
}

- except in this case a named property of the global object is created during variable instantiation for the global execution context but the function object is not created, and a reference to it assigned to the named property of the global object, until the assignment expression is evaluated. But the creation of the function object still happens in the global execution context so the [[scope]] property of the created function object still only contains the global object in the assigned scope chain.

Inner function declarations and expressions result in function objects being created within the execution context of a function so they get more elaborate scope chains. Consider the following code, which defines a function with an inner function declaration and then executes the outer function:-

function exampleOuterFunction(formalParameter){
    function exampleInnerFuncitonDec(){
        ... // inner function body
    }
    ...  // the rest of the outer function body.
}

exampleOuterFunction( 5 );

The function object corresponding with the outer function declaration is created during variable instantiation in the global execution context so its [[scope]] property contains the one item scope chain with only the global object in it.

When the global code executes the call to the exampleOuterFunction a new execution context is created for that function call and an Activation/Variable object along with it. The scope of that new execution context becomes the chain consisting of the new Activation object followed by the chain refereed to by the outer function object’s [[scope]] property (just the global object). Variable instantiation for that new execution context results in the creation of a function object that corresponds with the inner function definition and the [[scope]] property of that function object is assigned the value of the scope from the execution context in which it was created. A scope chain that contains the Activation object followed by the global object.

So far this is all automatic and controlled by the structure and execution of the source code. The scope chain of the execution context defines the [[scope]] properties of the function objects created and the [[scope]] properties of the function objects define the scope for their execution contexts (along with the corresponding Activation object). But ECMAScript provides the with statement as a means of modifying the scope chain.

The with statement evaluates an expression and if that expression is an object it is added to the scope chain of the current execution context (in front of the Activation/Variable object). The with statement then executes another statement (that may itself be a block statement) and then restores the execution context’s scope chain to what it was before.

A function declaration could not be affected by a with statement as they result in the creation of function objects during variable instantiation, but a function expression can be evaluated inside a with statement:-

/* create a global variable - y - that refers to an object:- */
var y = {x:5}; // object literal with an - x - property
function exampleFuncWith(){
    var z;
    /* Add the object referred to by the global variable - y - to the
       front of he scope chain:-
    */
    with(y){
        /* evaluate a function expression to create a function object
           and assign a reference to that function object to the local
           variable - z - :-
        */
        z = function(){
            ... // inner function expression body;
        }
    }
    ...
}

/* execute the - exampleFuncWith - function:- */
exampleFuncWith();

When the exampleFuncWith function is called the resulting execution context has a scope chain consisting of its Activation object followed by the global object. The execution of the with statement adds the object referred to by the global variable y to the front of that scope chain during the evaluation of the function expression. The function object created by the evaluation of the function expression is assigned a [[scope]] property that corresponds with the scope of the execution context in which it is created. A scope chain consisting of object y followed by the Activation object from the execution context of the outer function call, followed by the global object.

When the block statement associated with the with statement terminates the scope of the execution context is restored (the y object is removed), but the function object has been created at that point and its [[scope]] property assigned a reference to a scope chain with the y object at its head.

Identifier Resolution

Identifiers are resolved against the scope chain. ECMA 262 categorises this as a keyword rather than an identifier, which is not unreasonable as it is always resolved dependent on the this value in the execution context in which it is used, without reference to the scope chain.

Identifier resolution starts with the first object in the scope chain. It is checked to see if it has a property with a name that corresponds with the identifier. Because the scope chain is a chain of objects this checking encompasses the prototype chain of that object (if it has one). If no corresponding value can be found on the first object in the scope chain the search progresses to the next object. And so on until one of the objects in the chain (or one of its prototypes) has a property with a name that corresponds with the identifier or the scope chain is exhausted.

The operation on the identifier happens in the same way as the use of property accessors on objects described above. The object identified in the scope chain as having the corresponding property takes the place of the object in the property accessor and the identifier acts as a property name for that object. The global object is always at the end of the scope chain.

As execution contexts associated with function calls will have the Activation/Variable object at the front of the chain, identifiers used in function bodies are effectively first checked to see whether they correspond with formal parameters, inner function declaration names or local variables. Those would be resolved as named properties of the Activation/Variable object.

Closures

Automatic Garbage Collection

ECMAScript uses automatic garbage collection. The specification does not define the details, leaving that to the implementers to sort out, and some implementations are known to give a very low priority to their garbage collection operations. But the general idea is that if an object becomes un-referable (by having no remaining references to it left accessible to executing code) it becomes available for garbage collection and will at some future point be destroyed and any resources it is consuming freed and returned to the system for re-use.

This would normally be the case upon exiting an execution context. The scope chain structure, the Activation/Variable object and any objects created within the execution context, including function objects, would no longer be accessible and so would become available for garbage collection.

Forming Closures

A closure is formed by returning a function object that was created within an execution context of a function call from that function call and assigning a reference to that inner function to a property of another object. Or by directly assigning a reference to such a function object to, for example, a global variable, a property of a globally accessible object or an object passed by reference as an argument to the outer function call. e.g:-

function exampleClosureForm(arg1, arg2){
    var localVar = 8;
    function exampleReturned(innerArg){
        return ((arg1 + arg2)/(innerArg + localVar));
    }
    /* return a reference to the inner function defined as -
       exampleReturned -:-
    */
    return exampleReturned;
}

var globalVar = exampleClosureForm(2, 4);

Now the function object created within the execution context of the call to exampleClosureForm cannot be garbage collected because it is referred to by a global variable and is still accessible, it can even be executed with globalVar(n).

But something a little more complicated has happened because the function object now referred to by globalVar was created with a [[scope]] property referring to a scope chain containing the Activation/Variable object belonging to the execution context in which it was created (and the global object). Now the Activation/Variable object cannot be garbage collected either as the execution of the function object referred to by globalVar will need to add the whole scope chain from its [[scope]] property to the scope of the execution context created for each call to it.

A closure is formed. The inner function object has the free variables and the Activation/Variable object on the function’s scope chain is the environment that binds them.

The Activation/Variable object is trapped by being referred to in the scope chain assigned to the internal [[scope]] property of the function object now referred to by the globalVar variable. The Activation/Variable object is preserved along with its state; the values of its properties. Scope resolution in the execution context of calls to the inner function will resolve identifiers that correspond with named properties of that Activation/Variable object as properties of that object. The value of those properties can still be read and set even though the execution context for which it was created has exited.

In the example above that Activation/Variable object has a state that represents the values of formal parameters, inner function definitions and local variables, at the time when the outer function returned (exited its execution context). The arg1 property has the value 2,the arg2 property the value 4, localVar the value 8 and an exampleReturned property that is a reference to the inner function object that was returned form the outer function. (We will be referring to this Activation/Variable object as “ActOuter1″ in later discussion, for convenience.)

If the exampleClosureForm function was called again as:-

var secondGlobalVar = exampleClosureForm(12, 3);

- a new execution context would be created, along with a new Activation object. And a new function object would be returned, with its own distinct [[scope]] property referring to a scope chain containing the Activation object form this second execution context, with arg1 being 12 and arg2 being 3. (We will be referring to this Activation/Variable object as “ActOuter2″ in later discussion, for convenience.)

A second and distinct closure has been formed by the second execution of exampleClosureForm.

The two function objects created by the execution of exampleClosureForm to which references have been assigned to the global variable globalVar and secondGlobalVar respectively, return the expression ((arg1 + arg2)/(innerArg + localVar)). Which applies various operators to four identifiers. How these identifiers are resolved is critical to the use and value of closures.

Consider the execution of the function object referred to by globalVar, as globalVar(2). A new execution context is created and an Activation object (we will call it “ActInner1″), which is added to the head of the scope chain referred to the [[scope]] property of the executed function object. ActInner1 is given a property named innerArg, after its formal parameter and the argument value 2 assigned to it. The scope chain for this new execution context is: ActInner1-> ActOuter1-> global object.

Identifier resolution is done against the scope chain so in order to return the value of the expression ((arg1 + arg2)/(innerArg + localVar)) the values of the identifiers will be determined by looking for properties, with names corresponding with the identifiers, on each object in the scope chain in turn.

The first object in the chain is ActInner1 and it has a property named innerArg with the value 2. All of the other 3 identifiers correspond with named properties of ActOuter1; arg1 is 2, arg2 is 4 and localVar is 8. The function call returns ((2 + 4)/(2 + 8)).

Compare that with the execution of the otherwise identical function object referred to by secondGlobalVar, as secondGlobalVar(5). Calling the Activation object for this new execution context “ActInner2″, the scope chain becomes: ActInner2-> ActOuter2-> global object. ActInner2 returns innerArg as 5 and ActOuter2 returns arg1, arg2 and localVar as 12, 3 and 8 respectively. The value returned is ((12 + 3)/(5 + 8)).

Execute secondGlobalVar again and a new Activation object will appear at the front of the scope chain but ActOuter2 will still be next object in the chain and the value of its named properties will again be used in the resolution of the identifiers arg1, arg2 and localVar.

This is how ECMAScript inner functions gain, and maintain, access to the formal parameters, declared inner functions and local variables of the execution context in which they were created. And it is how the forming of a closure allows such a function object to keep referring to those values, reading and writing to them, for as long as it continues to exist. The Activation/Variable object from the execution context in which the inner function was created remains on the scope chain referred to by the function object’s [[scope]] property, until all references to the inner function are freed and the function object is made available for garbage collection (along with any now unneeded objects on its scope chain).

Inner function may themselves have inner functions, and the inner functions returned from the execution of functions to form closures may themselves return inner functions and form closures of their own. With each nesting the scope chain gains extra Activation objects originating with the execution contexts in which the inner function objects were created. The ECMAScript specification requires a scope chain to be finite, but imposes no limits on their length. Implementations probably do impose some practical limitation but no specific magnitude has yet been reported. The potential for nesting inner functions seems so far to have exceeded anyone’s desire to code them.

What can be done with Closures?

Strangely the answer to that appears to be anything and everything. I am told that closures enable ECMAScript to emulate anything, so the limitation is the ability to conceive and implement the emulation. That is a bit esoteric and it is probably better to start with something a little more practical.

Example 1: setTimeout with Function References

A common use for a closure is to provide parameters for the execution of a function prior to the execution of that function. For example, when a function is to be provided as the first argument to the setTimout function that is common in web browser environments.

setTimeout schedules the execution of a function (or a string of javascript source code, but not in this context), provided as its first argument, after an interval expressed in milliseconds (as its second argument). If a piece of code wants to use setTimeout it calls the setTimeout function and passes a reference to a function object as the first argument and the millisecond interval as the second, but a reference to a function object cannot provide parameters for the scheduled execution of that function.

However, code could call another function that returned a reference to an inner function object, with that inner function object being passed by reference to the setTimeout function. The parameters to be used for the execution of the inner function are passed with the call to the function that returns it. setTimout executes the inner function without passing arguments but that inner function can still access the parameters provided by the call to the outer function that returned it:-

function callLater(paramA, paramB, paramC){
    /* Return a reference to an anonymous inner function created
       with a function expression:-
    */
    return (function(){
        /* This inner function is to be executed with - setTimeout
           - and when it is executed it can read, and act upon, the
           parameters passed to the outer function:-
        */
        paramA[paramB] = paramC;
    });
}

...

/* Call the function that will return a reference to the inner function
   object created in its execution context. Passing the parameters that
   the inner function will use when it is eventually executed as
   arguments to the outer function. The returned reference to the inner
   function object is assigned to a local variable:-
*/
var functRef = callLater(elStyle, "display", "none");
/* Call the setTimeout function, passing the reference to the inner
   function assigned to the - functRef - variable as the first argument:-
*/
hideMenu=setTimeout(functRef, 500);

Example 2: Associating Functions with Object Instance Methods

There are many other circumstances when a reference to a function object is assigned so that it would be executed at some future time where it is useful to provide parameters for the execution of that function that would not be easily available at the time of execution but cannot be known until the moment of assignment.

One example might be a javascript object that is designed to encapsulate the interactions with a particular DOM element. It has doOnClick, doMouseOver and doMouseOut methods and wants to execute those methods when the corresponding events are triggered on the DOM element, but there may be any number of instances of the javascript object created associated with different DOM elements and the individual object instances do not know how they will be employed by the code that instantiated them. The object instances do not know how to reference themselves globally because they do not know which global variables (if any) will be assigned references to their instances.

So the problem is to execute an event handling function that has an association with a particular instance of the javascript object, and knows which method of that object to call.

The following example uses a small generalised closure based function that associates object instances with element event handlers. Arranging that the execution of the event handler calls the specified method of the object instance, passing the event object and a reference to the associated element on to the object method and returning the method’s return value.

/* A general function that associates an object instance with an event
   handler. The returned inner function is used as the event handler.
   The object instance is passed as the - obj - parameter and the name
   of the method that is to be called on that object is passed as the -
   methodName - (string) parameter.
*/
function associateObjWithEvent(obj, methodName){
    /* The returned inner function is intended to act as an event
       handler for a DOM element:-
    */
    return (function(e){
        /* The event object that will have been parsed as the - e -
           parameter on DOM standard browsers is normalised to the IE
           event object if it has not been passed as an argument to the
           event handling inner function:-
        */
        e = e||window.event;
        /* The event handler calls a method of the object - obj - with
           the name held in the string - methodName - passing the now
           normalised event object and a reference to the element to
           which the event handler has been assigned using the - this -
           (which works because the inner function is executed as a
           method of that element because it has been assigned as an
           event handler):-
        */
        return obj[methodName](e, this);
    });
}

/* This constructor function creates objects that associates themselves
   with DOM elements whose IDs are passed to the constructor as a
   string. The object instances want to arrange than when the
   corresponding element triggers onclick, onmouseover and onmouseout
   events corresponding methods are called on their object instance.
*/
function DhtmlObject(elementId){
    /* A function is called that retrieves a reference to the DOM
       element (or null if it cannot be found) with the ID of the
       required element passed as its argument. The returned value
       is assigned to the local variable - el -:-
    */
    var el = getElementWithId(elementId);
    /* The value of - el - is internally type-converted to boolean for
       the - if - statement so that if it refers to an object the
       result will be true, and if it is null the result false. So that
       the following block is only executed if the - el - variable
       refers to a DOM element:-
    */
    if(el){
        /* To assign a function as the element's event handler this
           object calls the - associateObjWithEvent - function
           specifying itself (with the - this - keyword) as the object
           on which a method is to be called and providing the name of
           the method that is to be called. The - associateObjWithEvent
           - function will return a reference to an inner function that
           is assigned to the event handler of the DOM element. That
           inner function will call the required method on the
           javascript object when it is executed in response to
           events:-
        */
        el.onclick = associateObjWithEvent(this, "doOnClick");
        el.onmouseover = associateObjWithEvent(this, "doMouseOver");
        el.onmouseout = associateObjWithEvent(this, "doMouseOut");
        ...
    }
}
DhtmlObject.prototype.doOnClick = function(event, element){
    ... // doOnClick method body.
}
DhtmlObject.prototype.doMouseOver = function(event, element){
    ... // doMouseOver method body.
}
DhtmlObject.prototype.doMouseOut = function(event, element){
    ... // doMouseOut method body.
}

And so any instances of the DhtmlObject can associate themselves with the DOM element that they are interested in without any need to know anything about how they are being employed by other code, impacting on the global namespace or risking clashes with other instances of the DhtmlObject.

Example 3: Encapsulating Related Functionality

Closures can be used to create additional scopes that can be used to group interrelated and dependent code in a way that minimises the risk of accidental interaction. Suppose a function is to build a string and to avoid the repeated concatenation operations (and the creation of numerous intermediate strings) the desire is to use an array to store the parts of the string in sequence and then output the results using the Array.prototype.join method (with an empty string as its argument). The array is going to act as a buffer for the output, but defining it locally to the function will result in its re-creation on each execution of the function, which may not be necessary if the only variable content of that array will be re-assigned on each function call.

One approach might make the array a global variable so that it can be re-used without being re-created. But the consequences of that will be that, in addition to the global variable that refers to the function that will use the buffer array, there will be a second global property that refers to the array itself. The effect is to render the code less manageable, as, if it is to be used elsewhere, its author has to remember to include both the function definition and the array definition. It also makes the code less easy to integrate with other code because instead of just ensuring that the function name is unique within the global namespace it is necessary to ensure that the Array on which it is dependent is using a name that is unique within the global namespace.

A Closure allows the buffer array to be associated (and neatly packaged) with the function that is dependent upon it and simultaneously keep the property name to which the buffer array as assigned out of the global namespace and free of the risk of name conflicts and accidental interactions.

The trick here is to create one additional execution context by executing a function expression in-line and have that function expression return an inner function that will be the function that is used by external code. The buffer array is then defined as a local variable of the function expression that is executed in-line. That only happens once so the Array is only created once, but is available to the function that depends on it for repeated use.

The following code creates a function that will return a string of HTML, much of which is constant, but those constant character sequences need to be interspersed with variable information provided as parameter to the function call.

A reference to an inner function object is returned from the in-line execution of a function expression and assigned to a global variable so that it can be called as a global function. The buffer array is defined as a local variable in the outer function expression. It is not exposed in the global namespace and does not need to be re-created whenever the function that uses it is called.

/* A global variable - getImgInPositionedDivHtml - is declared and
   assigned the value of an inner function expression returned from
   a one-time call to an outer function expression.

   That inner function returns a string of HTML that represents an
   absolutely positioned DIV wrapped round an IMG element, such that
   all of the variable attribute values are provided as parameters
   to the function call:-
*/
var getImgInPositionedDivHtml = (function(){
    /* The - buffAr - Array is assigned to a local variable of the
       outer function expression. It is only created once and that one
       instance of the array is available to the inner function so that
       it can be used on each execution of that inner function.

       Empty strings are used as placeholders for the date that is to
       be inserted into the Array by the inner function:-
    */
    var buffAr = [
        '<div id="',
        '',   //index 1, DIV ID attribute
        '" style="position:absolute;top:',
        '',   //index 3, DIV top position
        'px;left:',
        '',   //index 5, DIV left position
        'px;width:',
        '',   //index 7, DIV width
        'px;height:',
        '',   //index 9, DIV height
        'px;overflow:hidden;\"><img src=\"',
        '',   //index 11, IMG URL
        '\" width=\"',
        '',   //index 13, IMG width
        '\" height=\"',
        '',   //index 15, IMG height
        '\" alt=\"',
        '',   //index 17, IMG alt text
        '\"><\/div>'
    ];
    /* Return the inner function object that is the result of the
       evaluation of a function expression. It is this inner function
       object that will be executed on each call to -
       getImgInPositionedDivHtml( ... ) -:-
    */
    return (function(url, id, width, height, top, left, altText){
        /* Assign the various parameters to the corresponding
           locations in the buffer array:-
        */
        buffAr[1] = id;
        buffAr[3] = top;
        buffAr[5] = left;
        buffAr[13] = (buffAr[7] = width);
        buffAr[15] = (buffAr[9] = height);
        buffAr[11] = url;
        buffAr[17] = altText;
        /* Return the string created by joining each element in the
           array using an empty string (which is the same as just
           joining the elements together):-
        */
        return buffAr.join('');
    }); //:End of inner function expression.
})();
/*^^- :The inline execution of the outer function expression. */

If one function was dependent on one (or several) other functions, but those other functions were not expected to be directly employed by any other code, then the same technique could be used to group those functions with the one that was to be publicly exposed. Making a complex multi-function process into an easily portable and encapsulated unit of code.

Other Examples

Probably one of the best known applications of closures is Douglas Crockford’s technique for the emulation of private instance variables in ECMAScript objects. Which can be extended to all sorts of structures of scope contained nested accessibility/visibility, including the emulation of private static members for ECMAScript objects.

The possible application of closures are endless, understanding how they work is probably the best guide to realising how they can be used.

Accidental Closures

Rendering any inner function accessible outside of the body of the function in which it was created will form a closure. That makes closures very easy to create and one of the consequences is that javascript authors who do not appreciate closures as a language feature can observe the use of inner functions for various tasks and employ inner functions, with no apparent consequences, not realising that closures are being created or what the implications of doing that are.

Accidentally creating closures can have harmful side effects as the following section on the IE memory leak problem describes, but they can also impact of the efficiency of code. It is not the closures themselves, indeed carefully used they can contribute significantly towards the creation of efficient code. It is the use of inner functions that can impact on efficiency.

A common situation is where inner functions are used is as event handlers for DOM elements. For example the following code might be used to add an onclick handler to a link element:-

/* Define the global variable that is to have its value added to the
   - href - of a link as a query string by the following function:-
*/
var quantaty = 5;
/* When a link passed to this function (as the argument to the function
   call - linkRef -) an onclick event handler is added to the link that
   will add the value of a global variable - quantaty - to the - href -
   of that link as a query string, then return true so that the link
   will navigate to the resource specified by the - href - which will
   by then include the assigned query string:-
*/
function addGlobalQueryOnClick(linkRef){
    /* If the - linkRef - parameter can be type converted to true
       (which it will if it refers to an object):-
    */
    if(linkRef){
        /* Evaluate a function expression and assign a reference to the
           function object that is created by the evaluation of the
           function expression to the onclick handler of the link
           element:-
        */
        linkRef.onclick = function(){
            /* This inner function expression adds the query string to
               the - href - of the element to which it is attached as
               an event handler:-
            */
            this.href += ('?quantaty='+escape(quantaty));
            return true;
        };
    }
}

Whenever the addGlobalQueryOnClick function is called a new inner function is created (and a closure formed by its assignment). From the efficiency point of view that would not be significant if the addGlobalQueryOnClick function was only called once or twice, but if the function was heavily employed many distinct function objects would be created (one for each evaluation of the inner function expression).

The above code is not taking advantage of the fact that inner functions are becoming accessible outside of the function in which they are being created (or the resulting closures). As a result exactly the same effect could be achieved by defining the function that is to be used as the event handler separately and then assigning a reference to that function to the event handling property. Only one function object would be created and all of the elements that use that event handler would share a reference to that one function:-

/* Define the global variable that is to have its value added to the
   - href - of a link as a query string by the following function:-
*/
var quantaty = 5;

/* When a link passed to this function (as the argument to the function
   call - linkRef -) an onclick event handler is added to the link that
   will add the value of a global variable - quantaty - to the - href -
   of that link as a query string, then return true so that the link
   will navigate to the resource specified by the - href - which will
   by then include the assigned query string:-
*/
function addGlobalQueryOnClick(linkRef){
    /* If the - linkRef - parameter can be type converted to true
       (which it will if it refers to an object):-
    */
    if(linkRef){
        /* Assign a reference to a global function to the event
           handling property of the link so that it becomes the
           element's event handler:-
        */
        linkRef.onclick = forAddQueryOnClick;
    }
}
/* A global function declaration for a function that is intended to act
   as an event handler for a link element, adding the value of a global
   variable to the - href - of an element as an event handler:-
*/
function forAddQueryOnClick(){
    this.href += ('?quantaty='+escape(quantaty));
    return true;
}

As the inner function in the first version is not being used to exploit the closures produced by its use, it would be more efficient not to use an inner function, and thus not repeat the process of creating many essentially identical function objects.

A similar consideration applies to object constructor functions. It is not uncommon to see code similar to the following skeleton constructor:-

function ExampleConst(param){
    /* Create methods of the object by evaluating function expressions
       and assigning references to the resulting function objects
       to the properties of the object being created:-
    */
    this.method1 = function(){
        ... // method body.
    };
    this.method2 = function(){
        ... // method body.
    };
    this.method3 = function(){
        ... // method body.
    };
    /* Assign the constructor's parameter to a property of the object:-
    */
    this.publicProp = param;
}

Each time the constructor is used to create an object, with new ExampleConst(n), a new set of function objects are created to act as its methods. So the more object instances that are created the more function objects are created to go with them.

Douglas Crockford’s technique for emulating private members on javascript objects exploits the closure resulting form assigning references to inner function objects to the public properties of a constructed object from within its constructor. But if the methods of an object are not taking advantage of the closure that they will form within the constructor the creation of multiple function objects for each object instantiation will make the instantiation process slower and more resources will be consumed to accommodate the extra function objects created.

In that case it would be more efficient to create the function object once and assign references to them to the corresponding properties of the constructor’s prototype so they may be shared by all of the objects created with that constructor:-

function ExampleConst(param){
    /* Assign the constructor's parameter to a property of the object:-
    */
    this.publicProp = param;
}
/* Create methods for the objects by evaluating function expressions
   and assigning references to the resulting function objects to the
   properties of the constructor's prototype:-
*/
ExampleConst.prototype.method1 = function(){
    ... // method body.
};
ExampleConst.prototype.method2 = function(){
    ... // method body.
};
ExampleConst.prototype.method3 = function(){
    ... // method body.
};

The Internet Explorer Memory Leak Problem

The Internet Explorer web browser (verified on versions 4 to 6 (6 is current at the time of writing)) has a fault in its garbage collection system that prevents it from garbage collecting ECMAScript and some host objects if those host objects form part of a “circular” reference. The host objects in question are any DOM Nodes (including the document object and its descendants) and ActiveX objects. If a circular reference is formed including one or more of them, then none of the objects involved will be freed until the browser is closed down, and the memory that they consume will be unavailable to the system until that happens.

A circular reference is when two or more objects refer to each other in a way that can be followed and lead back to the starting point. Such as object 1 has a property that refers to object 2, object 2 has a property that refers to object 3 and object 3 has a property that refers back to object 1. With pure ECMAScript objects as soon as no other objects refer to any of objects 1, 2 or 3 the fact that they only refer to each other is recognised and they are made available for garbage collection. But on Internet Explorer, if any of those objects happen to be a DOM Node or ActiveX object, the garbage collection cannot see that the circular relationship between them is isolated from the rest of the system and free them. Instead they all stay in memory until the browser is closed.

Closures are extremely good at forming circular references. If a function object that forms a closure is assigned as, for example, and event handler on a DOM Node, and a reference to that Node is assigned to one of the Activation/Variable objects in its scope chain then a circular reference exists. DOM_Node.onevent -> function_object.[[scope]] -> scope_chain -> Activation_object.nodeRef -> DOM_Node. It is very easy to do, and a bit of browsing around a site that forms such a reference in a piece of code common to each page can consume most of the systems memory (possibly all).

Care can be taken to avoid forming circular references and remedial action can be taken when they cannot otherwise be avoided, such as using IE’s onunload event to null event handling function references. Recognising the problem and understanding closures (and their mechanism) is the key to avoiding this problem with IE.

comp.lang.javascript FAQ notes T.O.C.

  • Written by Richard Cornford. March 2004.
  • With corrections and suggestions by:-
    • Martin Honnen.
    • Yann-Erwan Perio (Yep).
    • Lasse Reichstein Nielsen. (definition of closure)
    • Mike Scirocco.
    • Dr John Stockton.
Digg This
Reddit This
Stumble Now!
Buzz This
Vote on DZone
Share on Facebook
Bookmark this on Delicious
Kick It on DotNetKicks.com
Shout it
Share on LinkedIn
Bookmark this on Technorati
Post on Twitter
Google Buzz (aka. Google Reader)